explorer: Use humanize

This commit is contained in:
Andras Slemmer 2016-09-16 16:00:24 +01:00
parent 75ee91fe4e
commit df57f5cf5e
6 changed files with 30 additions and 44 deletions

View File

@ -71,4 +71,7 @@ dependencies {
// JFXtras: useful widgets including a calendar control. // JFXtras: useful widgets including a calendar control.
compile 'org.jfxtras:jfxtras-agenda:8.0-r5' compile 'org.jfxtras:jfxtras-agenda:8.0-r5'
compile 'org.jfxtras:jfxtras-font-roboto:8.0-r5' compile 'org.jfxtras:jfxtras-font-roboto:8.0-r5'
// Humanize: formatting
compile 'com.github.mfornos:humanize-icu:1.2.2'
} }

View File

@ -1,12 +1,16 @@
package com.r3corda.explorer.formatters package com.r3corda.explorer.formatters
import com.ibm.icu.text.DecimalFormat
import com.r3corda.core.contracts.Amount import com.r3corda.core.contracts.Amount
import java.text.DecimalFormat import humanize.icu.spi.context.DefaultICUContext
import java.util.* import java.util.Currency
class AmountFormatter { class AmountFormatter {
companion object { companion object {
val icuContext = DefaultICUContext()
fun currency(formatter: Formatter<Amount<Currency>>) = object : Formatter<Amount<Currency>> { fun currency(formatter: Formatter<Amount<Currency>>) = object : Formatter<Amount<Currency>> {
override fun format(value: Amount<Currency>) = override fun format(value: Amount<Currency>) =
"${value.token.currencyCode} ${formatter.format(value)}" "${value.token.currencyCode} ${formatter.format(value)}"
@ -17,31 +21,14 @@ class AmountFormatter {
NumberFormatter.doubleComma.format(value.quantity / 100.0) NumberFormatter.doubleComma.format(value.quantity / 100.0)
} }
private data class KmbRange(val fromLog: Double, val toLog: Double, val letter: String, val divider: (Double) -> Double) val compact = object : Formatter<Amount<Currency>> {
private val kmbRanges = listOf( val decimalFormat = (icuContext.compactDecimalFormat as DecimalFormat).apply {
KmbRange(Double.NEGATIVE_INFINITY, Math.log(1000.0), "", { value -> value }), minimumFractionDigits = 0
KmbRange(Math.log(1000.0), Math.log(1000000.0), "k", { value -> value / 1000.0 }), maximumFractionDigits = 4
KmbRange(Math.log(1000000.0), Math.log(1000000000.0), "m", { value -> value / 1000000.0 }), setSignificantDigitsUsed(false)
KmbRange(Math.log(1000000000.0), Double.POSITIVE_INFINITY, "b", { value -> value / 1000000000.0 }) }
)
fun kmb(formatter: Formatter<Double>) = object : Formatter<Amount<Currency>> {
override fun format(value: Amount<Currency>): String { override fun format(value: Amount<Currency>): String {
val displayAmount = value.quantity / 100.0 return decimalFormat.format(value.quantity / 100.0)
val logarithm = Math.log(displayAmount)
val rangeIndex = kmbRanges.binarySearch(
comparison = { range ->
if (logarithm < range.fromLog) {
1
} else if (logarithm < range.toLog) {
0
} else {
-1
}
}
)
val kmbRange = kmbRanges[rangeIndex]
return "${formatter.format(kmbRange.divider(displayAmount))}${kmbRange.letter}"
} }
} }
} }

View File

@ -1,6 +1,6 @@
package com.r3corda.explorer.formatters package com.r3corda.explorer.formatters
interface Formatter<T> { interface Formatter<in T> {
fun format(value: T): String fun format(value: T): String
} }

View File

@ -8,18 +8,15 @@ class NumberFormatter {
private val doubleCommaFormatter = DecimalFormat("#,###.00") private val doubleCommaFormatter = DecimalFormat("#,###.00")
private val integralCommaFormatter = DecimalFormat("#,###") private val integralCommaFormatter = DecimalFormat("#,###")
val doubleComma = object : Formatter<Double> { private val _integralComma: Formatter<Any> = object : Formatter<Any> {
override fun format(value: Double) = override fun format(value: Any) = integralCommaFormatter.format(value)
doubleCommaFormatter.format(value)
} }
val longComma = object : Formatter<Long> { val doubleComma = object : Formatter<Double> {
override fun format(value: Long) = override fun format(value: Double) = doubleCommaFormatter.format(value)
integralCommaFormatter.format(value)
}
val intComma = object : Formatter<Int> {
override fun format(value: Int) =
integralCommaFormatter.format(value)
} }
val numberComma: Formatter<Number> = _integralComma
val longComma: Formatter<Long> = _integralComma
} }
} }

View File

@ -302,7 +302,7 @@ class CashViewer : View() {
"Total $it position$plural" "Total $it position$plural"
}) })
val equivSumLabelFormatter = AmountFormatter.currency(AmountFormatter.kmb(NumberFormatter.doubleComma)) val equivSumLabelFormatter = AmountFormatter.currency(AmountFormatter.compact)
equivSumLabel.textProperty().bind(selectedViewerNodeSumEquiv.map { equivSumLabel.textProperty().bind(selectedViewerNodeSumEquiv.map {
equivSumLabelFormatter.format(it) equivSumLabelFormatter.format(it)
}) })

View File

@ -1,6 +1,7 @@
package com.r3corda.explorer.views package com.r3corda.explorer.views
import com.r3corda.client.fxutils.AmountBindings import com.r3corda.client.fxutils.AmountBindings
import com.r3corda.client.fxutils.map
import com.r3corda.client.model.* import com.r3corda.client.model.*
import com.r3corda.contracts.asset.Cash import com.r3corda.contracts.asset.Cash
import com.r3corda.core.contracts.StateAndRef import com.r3corda.core.contracts.StateAndRef
@ -40,15 +41,15 @@ class Home : View() {
private val exchangeRate: ObservableValue<ExchangeRate> by observableValue(ExchangeRateModel::exchangeRate) private val exchangeRate: ObservableValue<ExchangeRate> by observableValue(ExchangeRateModel::exchangeRate)
private val sumAmount = AmountBindings.sumAmountExchange( private val sumAmount = AmountBindings.sumAmountExchange(
EasyBind.map(cashStates) { it.state.data.amount.withoutIssuer() }, cashStates.map { it.state.data.amount.withoutIssuer() },
reportingCurrency, reportingCurrency,
exchangeRate exchangeRate
) )
init { init {
val formatter = AmountFormatter.currency(AmountFormatter.kmb(NumberFormatter.doubleComma)) val formatter = AmountFormatter.currency(AmountFormatter.compact)
ourCashLabel.textProperty().bind(EasyBind.map(sumAmount) { formatter.format(it) }) ourCashLabel.textProperty().bind(sumAmount.map { formatter.format(it) })
ourCashPane.setOnMouseClicked { clickEvent -> ourCashPane.setOnMouseClicked { clickEvent ->
if (clickEvent.button == MouseButton.PRIMARY) { if (clickEvent.button == MouseButton.PRIMARY) {
selectedView.value = SelectedView.Cash selectedView.value = SelectedView.Cash
@ -56,9 +57,7 @@ class Home : View() {
} }
ourTransactionsLabel.textProperty().bind( ourTransactionsLabel.textProperty().bind(
Bindings.createStringBinding({ Bindings.size(gatheredTransactionDataList).map { NumberFormatter.numberComma.format(it) }
NumberFormatter.intComma.format(gatheredTransactionDataList.size)
}, arrayOf(gatheredTransactionDataList))
) )
ourTransactionsPane.setOnMouseClicked { clickEvent -> ourTransactionsPane.setOnMouseClicked { clickEvent ->
if (clickEvent.button == MouseButton.PRIMARY) { if (clickEvent.button == MouseButton.PRIMARY) {