Skip to content

Commit

Permalink
improve total preview formatting to cap large numbers, clarify the me…
Browse files Browse the repository at this point in the history
…aning of formatFourSigFigs
  • Loading branch information
norwnd committed Jan 25, 2025
1 parent 367b822 commit e3d93a4
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 126 deletions.
2 changes: 1 addition & 1 deletion client/webserver/site/src/js/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ export default class Application {
rows.appendChild(row)
row.classList.add('p-2', 'hoverbg', 'pointer')
Doc.bind(row, 'click', () => {
Doc.setText(el, '[data-value]', Doc.formatFourSigFigs(atoms / cFactor, Math.round(Math.log10(cFactor))))
Doc.setText(el, '[data-value]', Doc.formatBestWeCan(atoms / cFactor, Math.round(Math.log10(cFactor))))
Doc.setText(el, '[data-unit]', unit)
})
}
Expand Down
40 changes: 17 additions & 23 deletions client/webserver/site/src/js/doc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,16 @@ export default class Doc {
return d
}

/*
* capNumberStr caps number string at maxDigits by trimming least-significant digits.
*/
static capNumberStr (numberStr: string, maxDigits: number): string {
if (numberStr.length <= maxDigits) {
return numberStr
}
return numberStr.substring(0, maxDigits)
}

/*
* formatCoinAtom formats the value in atomic units into a string
* representation in conventional units. If the value happens to be an
Expand Down Expand Up @@ -383,18 +393,6 @@ export default class Doc {
return fullPrecisionFormatterWithPreservingZeroes(lotSizeDigits + rateStepDigits).format(coin)
}

/*
* formatCoinAtomFourSigFigs should actually be called formatCoinAtomBestWeCan, but
* this name is left for compatibility purposes (simpler to rebase onto upstream).
*
* formatCoinAtomFourSigFigs is similar to formatCoinAtom but is more flexible
* in the way it treats decimals (can omit them if necessary).
*/
static formatCoinAtomFourSigFigs (coinAtom: number, unitInfo?: UnitInfo): string {
const [v, precisionFull] = convertToConventional(coinAtom, unitInfo)
return Doc.formatFourSigFigs(v, precisionFull)
}

// adjRateAtomsBuy helps us make sure every order-rate we've got is adjusted to rate-step,
// this is redundant but helps with the hack we do to keep rates manageable in UI
// (see comment that mentions "insanely large rate-step"); note, we have to round
Expand Down Expand Up @@ -450,21 +448,17 @@ export default class Doc {
}

/*
* formatFourSigFigs should actually be called formatBestWeCan, but this name is
* left for compatibility purposes (simpler to rebase onto upstream).
*
* formatFourSigFigs formats number n using 4 decimals at most, sacrificing
* them as needed. Parameter maxDecimals helps it figure our if it even needs all 4
* digits or not (e.g. if maxDecimals is 2 there is no point in displaying 4 digits).
* formatBestWeCan formats number n to the best of its ability to keep it short
* sacrificing as little precision as possible.
*/
static formatFourSigFigs (n: number, maxDecimals?: number): string {
static formatBestWeCan (n: number, maxDecimals?: number): string {
if (n >= 1000) {
// can't show decimals, might as well format as integer
// for large numbers don't want to show decimals, might as well format as integer
return intFormatter.format(n)
}
if (!maxDecimals) {
// since maxDecimals is not specified formatting with fourSigFigs is
// the best we can do here
// since maxDecimals is not specified formatting with fourSigFigs is the best
// guess we'll go with
return fourSigFigs.format(n)
}
// otherwise it's best to format with full precision up to maxDecimals
Expand Down Expand Up @@ -542,7 +536,7 @@ export default class Doc {
*/
static formatBestUnitsFourSigFigs (atoms: number, ui: UnitInfo, prefs?: Record<string, boolean>): [string, string] {
const [v, prec, unit] = this.bestConversion(atoms, ui, prefs)
return [Doc.formatFourSigFigs(v, prec), unit]
return [Doc.formatBestWeCan(v, prec), unit]
}

/*
Expand Down
24 changes: 12 additions & 12 deletions client/webserver/site/src/js/forms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -825,20 +825,20 @@ export class ConfirmRegistrationForm {
const bondLockConventional = bondLock / conversionFactor
page.tradingTier.textContent = String(tier)
page.logo.src = Doc.logoPath(asset.symbol)
page.bondLock.textContent = Doc.formatFourSigFigs(bondLockConventional)
page.bondLock.textContent = Doc.formatBestWeCan(bondLockConventional)
page.bondUnit.textContent = unit
const r = app().fiatRatesMap[assetID]
Doc.show(page.bondLockUSDBox)
if (r) page.bondLockUSD.textContent = Doc.formatFourSigFigs(bondLockConventional * r)
if (r) page.bondLockUSD.textContent = Doc.formatBestWeCan(bondLockConventional * r)
else Doc.hide(page.bondLockUSDBox)
if (fees) page.feeReserves.textContent = Doc.formatFourSigFigs(fees / conversionFactor)
if (fees) page.feeReserves.textContent = Doc.formatBestWeCan(fees / conversionFactor)
page.reservesUnit.textContent = unit
}

setFees (assetID: number, fees: number) {
this.fees = fees
const conversionFactor = app().assets[assetID].unitInfo.conventional.conversionFactor
this.page.feeReserves.textContent = Doc.formatFourSigFigs(fees / conversionFactor)
this.page.feeReserves.textContent = Doc.formatBestWeCan(fees / conversionFactor)
}

/* Form expands into its space quickly from the lower-right as it fades in. */
Expand Down Expand Up @@ -1002,10 +1002,10 @@ export class FeeAssetSelectionForm {
Doc.bind(tr, 'click', () => { this.assetSelected(assetID) })
tmpl.feeSymbol.textContent = unit
const bondSizeConventional = bondAsset.amount / conversionFactor
tmpl.feeAmt.textContent = Doc.formatFourSigFigs(bondSizeConventional)
tmpl.feeAmt.textContent = Doc.formatBestWeCan(bondSizeConventional)
const fiatRate = app().fiatRatesMap[assetID]
Doc.setVis(fiatRate, tmpl.fiatBox)
if (fiatRate) tmpl.fiatBondAmount.textContent = Doc.formatFourSigFigs(bondSizeConventional * fiatRate)
if (fiatRate) tmpl.fiatBondAmount.textContent = Doc.formatBestWeCan(bondSizeConventional * fiatRate)
this.assetRows[assetID] = { ready: tmpl.ready }
}

Expand All @@ -1029,12 +1029,12 @@ export class FeeAssetSelectionForm {
const conventionalLotSize = lotSize / bui.conventional.conversionFactor
const startingLimit = conventionalLotSize * parcelSize * perTierBaseParcelLimit * tier
const privilegedLimit = conventionalLotSize * parcelSize * perTierBaseParcelLimit * parcelLimitScoreMultiplier * tier
tmpl.tradeLimitLow.textContent = Doc.formatFourSigFigs(startingLimit)
tmpl.tradeLimitHigh.textContent = Doc.formatFourSigFigs(privilegedLimit)
tmpl.tradeLimitLow.textContent = Doc.formatBestWeCan(startingLimit)
tmpl.tradeLimitHigh.textContent = Doc.formatBestWeCan(privilegedLimit)
const baseFiatRate = app().fiatRatesMap[baseID]
if (baseFiatRate) {
tmpl.fiatTradeLimitLow.textContent = Doc.formatFourSigFigs(startingLimit * baseFiatRate)
tmpl.fiatTradeLimitHigh.textContent = Doc.formatFourSigFigs(privilegedLimit * baseFiatRate)
tmpl.fiatTradeLimitLow.textContent = Doc.formatBestWeCan(startingLimit * baseFiatRate)
tmpl.fiatTradeLimitHigh.textContent = Doc.formatBestWeCan(privilegedLimit * baseFiatRate)
}
Doc.setVis(baseFiatRate, page.fiatTradeLowBox, page.fiatTradeHighBox)
}
Expand Down Expand Up @@ -1109,7 +1109,7 @@ export class FeeAssetSelectionForm {
const bondLock = bondAsset.amount * tier * bondReserveMultiplier
page.bondLockDisplay.textContent = Doc.formatCoinAtom(bondLock, ui)
const fiatRate = app().fiatRatesMap[assetID]
if (fiatRate) page.fiatLockDisplay.textContent = Doc.formatFourSigFigs(bondLock / conversionFactor * fiatRate)
if (fiatRate) page.fiatLockDisplay.textContent = Doc.formatBestWeCan(bondLock / conversionFactor * fiatRate)
for (const m of Object.values(this.marketRows)) m.setTier(tier)
const currentBondAmts: Record<number, number> = {}
for (const [assetIDStr, { wallet }] of Object.entries(app().assets)) {
Expand All @@ -1136,7 +1136,7 @@ export class FeeAssetSelectionForm {
tmpl.name.textContent = name
const fiatRate = app().fiatRatesMap[assetID]
Doc.setVis(tmpl.fiatBox)
if (fiatRate) tmpl.fiatAmt.textContent = Doc.formatFourSigFigs(bondLocked / conversionFactor * fiatRate)
if (fiatRate) tmpl.fiatAmt.textContent = Doc.formatBestWeCan(bondLocked / conversionFactor * fiatRate)
}
}
Doc.setVis(fiatRate, page.fiatLockBox)
Expand Down
28 changes: 16 additions & 12 deletions client/webserver/site/src/js/markets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -721,10 +721,10 @@ export default class MarketsPage extends BasePage {

const { unitInfo: { conventional: { conversionFactor: cFactor, unit } } } = xc.assets[mkt.baseid]
if (baseFiatRate) {
this.stats.tmpl.volume24.textContent = Doc.formatFourSigFigs(mkt.spot.vol24 / cFactor * baseFiatRate)
this.stats.tmpl.volume24.textContent = Doc.formatBestWeCan(mkt.spot.vol24 / cFactor * baseFiatRate)
this.stats.tmpl.volume24Unit.textContent = 'USD'
} else {
this.stats.tmpl.volume24.textContent = Doc.formatFourSigFigs(mkt.spot.vol24 / cFactor)
this.stats.tmpl.volume24.textContent = Doc.formatBestWeCan(mkt.spot.vol24 / cFactor)
this.stats.tmpl.volume24Unit.textContent = unit
}

Expand Down Expand Up @@ -1493,31 +1493,33 @@ export default class MarketsPage extends BasePage {
const page = this.page
const market = this.market

const maxDigits = 9 // how large a formatted number can be (for total preview)

if (orderQtyAtom > 0 && orderRateAtom > 0) {
const totalOut = orderQtyAtom * orderRateAtom / OrderUtil.RateEncodingFactor
const totalIn = orderQtyAtom

page.orderTotalPreviewBuyLeft.textContent = intl.prep(
intl.ID_LIMIT_ORDER_BUY_SELL_OUT_TOTAL_PREVIEW,
{
total: Doc.formatCoinAtomToLotSizeQuoteCurrency(
total: Doc.capNumberStr(Doc.formatCoinAtomToLotSizeQuoteCurrency(
totalOut,
market.baseUnitInfo,
market.quoteUnitInfo,
market.cfg.lotsize,
market.cfg.ratestep
),
), maxDigits),
asset: market.quoteUnitInfo.conventional.unit
}
)
page.orderTotalPreviewBuyRight.textContent = intl.prep(
intl.ID_LIMIT_ORDER_BUY_SELL_IN_TOTAL_PREVIEW,
{
total: Doc.formatCoinAtomToLotSizeBaseCurrency(
total: Doc.capNumberStr(Doc.formatCoinAtomToLotSizeBaseCurrency(
totalIn,
market.baseUnitInfo,
market.cfg.lotsize
),
), maxDigits),
asset: market.baseUnitInfo.conventional.unit
}
)
Expand All @@ -1535,31 +1537,33 @@ export default class MarketsPage extends BasePage {
const page = this.page
const market = this.market

const maxDigits = 9 // how large a formatted number can be (for total preview)

if (orderQtyAtom > 0 && orderRateAtom > 0) {
const totalOut = orderQtyAtom * orderRateAtom / OrderUtil.RateEncodingFactor
const totalIn = orderQtyAtom

page.orderTotalPreviewSellLeft.textContent = intl.prep(
intl.ID_LIMIT_ORDER_BUY_SELL_OUT_TOTAL_PREVIEW,
{
total: Doc.formatCoinAtomToLotSizeBaseCurrency(
total: Doc.capNumberStr(Doc.formatCoinAtomToLotSizeBaseCurrency(
totalIn,
market.baseUnitInfo,
market.cfg.lotsize
),
), maxDigits),
asset: market.baseUnitInfo.conventional.unit
}
)
page.orderTotalPreviewSellRight.textContent = intl.prep(
intl.ID_LIMIT_ORDER_BUY_SELL_IN_TOTAL_PREVIEW,
{
total: Doc.formatCoinAtomToLotSizeQuoteCurrency(
total: Doc.capNumberStr(Doc.formatCoinAtomToLotSizeQuoteCurrency(
totalOut,
market.baseUnitInfo,
market.quoteUnitInfo,
market.cfg.lotsize,
market.cfg.ratestep
),
), maxDigits),
asset: market.quoteUnitInfo.conventional.unit
}
)
Expand Down Expand Up @@ -2590,13 +2594,13 @@ export default class MarketsPage extends BasePage {
const { auth } = app().exchanges[host]

page.parcelSizeLots.textContent = String(mkt.parcelsize)
page.marketLimitBase.textContent = Doc.formatFourSigFigs(mkt.parcelsize * mkt.lotsize / bui.conventional.conversionFactor)
page.marketLimitBase.textContent = Doc.formatBestWeCan(mkt.parcelsize * mkt.lotsize / bui.conventional.conversionFactor)
page.marketLimitBaseUnit.textContent = bui.conventional.unit
page.marketLimitQuoteUnit.textContent = qui.conventional.unit
const conversionRate = this.anyRate()[1]
if (conversionRate) {
const qty = mkt.lotsize * conversionRate
page.marketLimitQuote.textContent = Doc.formatFourSigFigs(mkt.parcelsize * qty / qui.conventional.conversionFactor)
page.marketLimitQuote.textContent = Doc.formatBestWeCan(mkt.parcelsize * qty / qui.conventional.conversionFactor)
} else page.marketLimitQuote.textContent = '-'

const tier = strongTier(auth)
Expand Down
Loading

0 comments on commit e3d93a4

Please sign in to comment.