From b6a4d6bf1a31396a193a93d42a8352cab8c37c35 Mon Sep 17 00:00:00 2001
From: domchan <31119455+domechn@users.noreply.github.com>
Date: Sun, 10 Dec 2023 14:49:13 +0300
Subject: [PATCH] optimize comparison style (#213)
* optimize comparison style
* optimize comparison style
* optimize comparison style
---
src/components/coin-analytics.tsx | 10 +-
.../{comparison/index.tsx => comparison.tsx} | 350 ++++++++----------
src/components/comparison/index.css | 46 ---
src/utils/currency.ts | 10 +
4 files changed, 175 insertions(+), 241 deletions(-)
rename src/components/{comparison/index.tsx => comparison.tsx} (50%)
delete mode 100644 src/components/comparison/index.css
diff --git a/src/components/coin-analytics.tsx b/src/components/coin-analytics.tsx
index 11caa55..4f7d03f 100644
--- a/src/components/coin-analytics.tsx
+++ b/src/components/coin-analytics.tsx
@@ -16,6 +16,7 @@ import { appCacheDir as getAppCacheDir } from "@tauri-apps/api/path";
import { useNavigate, useParams } from "react-router-dom";
import {
currencyWrapper,
+ prettyNumberKeepNDigitsAfterDecimalPoint,
prettyNumberToLocaleString,
prettyPriceNumberToLocaleString,
} from "@/utils/currency";
@@ -172,6 +173,11 @@ const App = ({
[currency, profit]
);
+ const maxPositionStr = useMemo(
+ () => prettyNumberKeepNDigitsAfterDecimalPoint(maxPosition, 8),
+ [maxPosition]
+ );
+
const profitRate = useMemo(
() =>
breakevenPrice === 0
@@ -434,9 +440,7 @@ const App = ({
max pos:{" "}
- {Number.isInteger(maxPosition)
- ? maxPosition
- : maxPosition.toFixed(8).replace(/0+$/, "")}
+ {maxPositionStr}
diff --git a/src/components/comparison/index.tsx b/src/components/comparison.tsx
similarity index 50%
rename from src/components/comparison/index.tsx
rename to src/components/comparison.tsx
index 6b04527..cba9173 100644
--- a/src/components/comparison/index.tsx
+++ b/src/components/comparison.tsx
@@ -1,14 +1,17 @@
-import { useContext, useEffect, useMemo, useState } from "react";
-import "./index.css";
+import { useEffect, useMemo, useState } from "react";
import { CoinData, CurrencyRateDetail } from "@/middlelayers/types";
import { queryAllDataDates, queryCoinDataByUUID } from "@/middlelayers/charts";
import _ from "lodash";
import ViewIcon from "@/assets/icons/view-icon.png";
import HideIcon from "@/assets/icons/hide-icon.png";
-import { currencyWrapper, prettyNumberToLocaleString } from "@/utils/currency";
-import { useWindowSize } from "@/utils/hook";
+import {
+ currencyWrapper,
+ prettyNumberKeepNDigitsAfterDecimalPoint,
+ prettyNumberToLocaleString,
+ prettyPriceNumberToLocaleString,
+} from "@/utils/currency";
import { parseDateToTS } from "@/utils/date";
-import { ButtonGroup, ButtonGroupItem } from "../ui/button-group";
+import { ButtonGroup, ButtonGroupItem } from "./ui/button-group";
import {
Select,
SelectContent,
@@ -17,11 +20,19 @@ import {
SelectLabel,
SelectTrigger,
SelectValue,
-} from "../ui/select";
-import { LoadingContext } from '@/App'
+} from "./ui/select";
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "./ui/table";
type ComparisonData = {
name: string;
+ type: "price" | "amount" | "value";
base: number;
head: number;
};
@@ -29,7 +40,6 @@ type ComparisonData = {
type QuickCompareType = "7D" | "1M" | "1Q" | "1Y";
const App = ({ currency }: { currency: CurrencyRateDetail }) => {
- const { setLoading } = useContext(LoadingContext);
const [baseId, setBaseId] = useState("");
const [dateOptions, setDateOptions] = useState<
{
@@ -41,8 +51,6 @@ const App = ({ currency }: { currency: CurrencyRateDetail }) => {
const [currentQuickCompare, setCurrentQuickCompare] =
useState(null);
- const windowSize = useWindowSize();
-
const baseDate = useMemo(() => {
return _.find(dateOptions, { value: "" + baseId })?.label;
}, [dateOptions, baseId]);
@@ -56,17 +64,25 @@ const App = ({ currency }: { currency: CurrencyRateDetail }) => {
const [data, setData] = useState([]);
- const [showDetail, setShowDetail] = useState(true);
-
- useEffect(() => {
- // it is a hack
- setLoading(true)
- // sleep 150ms
+ const [shouldMaskValue, setShowDetail] = useState(false);
- setTimeout(() => {
- setLoading(false)
- }, 150)
- },[])
+ const displayData = useMemo(() => {
+ return _(data)
+ .map((d) => ({
+ name: d.name,
+ type: d.type,
+ base: showColumnVal(d, "base"),
+ head: showColumnVal(d, "head"),
+ cmp: prettyComparisonResult(d.base, d.head),
+ color:
+ prettyComparisonResult(d.base, d.head) === "-"
+ ? "black"
+ : getComparisonResultNumber(d.base, d.head) > 0
+ ? "green"
+ : "red",
+ }))
+ .value();
+ }, [data, shouldMaskValue]);
useEffect(() => {
loadAllSelectDates().then((data) => {
@@ -99,14 +115,14 @@ const App = ({ currency }: { currency: CurrencyRateDetail }) => {
if (!baseId) {
return;
}
- loadDataByUUID(baseId).then((data) => setBaseData(data))
+ loadDataByUUID(baseId).then((data) => setBaseData(data));
}, [baseId]);
useEffect(() => {
if (!headId) {
return;
}
- loadDataByUUID(headId).then((data) => setHeadData(data))
+ loadDataByUUID(headId).then((data) => setHeadData(data));
}, [headId]);
// update quick compare data ( baseId and headId )
@@ -182,7 +198,7 @@ const App = ({ currency }: { currency: CurrencyRateDetail }) => {
}
function onViewOrHideClick() {
- setShowDetail(!showDetail);
+ setShowDetail(!shouldMaskValue);
}
function loadData(base: CoinData[], head: CoinData[]): ComparisonData[] {
@@ -192,26 +208,13 @@ const App = ({ currency }: { currency: CurrencyRateDetail }) => {
.uniq()
.value();
- const others = "Others";
-
- // add others to last
- symbols.sort((a, b) => {
- if (a === others) {
- return 1;
- }
- if (b === others) {
- return -1;
- }
- // origin order
- return 0;
- });
-
// make total value and amount as the first two items
const baseTotal = _(base).sumBy("value");
const headTotal = _(head).sumBy("value");
if (!_(symbols).isEmpty()) {
res.push({
name: "Total Value",
+ type: "value",
base: baseTotal,
head: headTotal,
});
@@ -221,33 +224,31 @@ const App = ({ currency }: { currency: CurrencyRateDetail }) => {
const baseItem = _.find(base, { symbol });
const headItem = _.find(head, { symbol });
- res.push({
- name: symbol + " Value",
- base: baseItem?.value || 0,
- head: headItem?.value || 0,
- });
-
- if (symbol === others) {
- return;
- }
-
res.push({
name: symbol + " Amount",
+ type: "amount",
base: baseItem?.amount || 0,
head: headItem?.amount || 0,
});
res.push({
name: symbol + " Price",
+ type: "price",
base: baseItem?.price || 0,
head: headItem?.price || 0,
});
+
+ res.push({
+ name: symbol + " Value",
+ type: "value",
+ base: baseItem?.value || 0,
+ head: headItem?.value || 0,
+ });
});
return res;
}
async function loadDataByUUID(uuid: string): Promise {
- // return queryCoinDataById(id);
const data = await queryCoinDataByUUID(uuid);
const reversedData = _(data).sortBy("value").reverse().value();
@@ -263,25 +264,26 @@ const App = ({ currency }: { currency: CurrencyRateDetail }) => {
function prettyComparisonResult(base: number, head: number): string {
const per = getComparisonResultNumber(base, head);
+ const perStr = prettyNumberToLocaleString(per < 0 ? -per : per);
- if (per === 0) {
+ if (perStr === "0.00" || perStr === "-0.00") {
return "-";
}
if (per > 0) {
- return "↑ " + prettyNumber(per, false) + "%";
+ return "↑ " + perStr + "%";
}
- return "↓ " + -prettyNumber(per, false) + "%";
+ return "↓ " + perStr + "%";
}
function prettyNumber(
number: number,
- keepDecimal: boolean,
- showRealNumber = true,
+ type: "price" | "amount" | "value",
+ shouldMask = false,
convertCurrency = false
): string {
- if (!showRealNumber) {
+ if (shouldMask) {
return "***";
}
if (!number) {
@@ -292,7 +294,11 @@ const App = ({ currency }: { currency: CurrencyRateDetail }) => {
convertedNumber = currencyWrapper(currency)(number);
}
let res = "" + convertedNumber;
- if (!keepDecimal) {
+ if (type === "price") {
+ res = prettyPriceNumberToLocaleString(convertedNumber);
+ } else if (type === "amount") {
+ res = prettyNumberKeepNDigitsAfterDecimalPoint(convertedNumber, 8);
+ } else if (type === "value") {
res = prettyNumberToLocaleString(convertedNumber);
}
if (convertCurrency) {
@@ -305,12 +311,14 @@ const App = ({ currency }: { currency: CurrencyRateDetail }) => {
item: ComparisonData,
valType: "base" | "head"
): string {
+ const shouldMask = shouldMaskValue && item.type !== "price";
+ const shouldConvertCurrency =
+ item.type === "price" || item.type === "value";
return prettyNumber(
_(item).get(valType),
- item.name.includes("Amount") || item.name.includes("Price"),
- // don't hide price
- showDetail || item.name.includes("Price"),
- item.name.includes("Price") || item.name.includes("Value")
+ item.type,
+ shouldMask,
+ shouldConvertCurrency
);
}
@@ -320,143 +328,101 @@ const App = ({ currency }: { currency: CurrencyRateDetail }) => {
return (
<>
-
-
-
-
-
- Quick Compare
-
-
- onQuickCompareButtonClick(val as QuickCompareType)
- }
- >
- 7D
- 1M
- 1Q
- 1Y
-
-
-
-
-
-
+
+
+
-
-
+
+ Quick Compare
-
- {_(data).isEmpty() ? (
- "No Data"
- ) : (
-
+ onQuickCompareButtonClick(val as QuickCompareType)
+ }
>
-
- Name
-
-
{baseDate}
-
- Difference
-
-
{headDate}
-
+
7D
+
1M
+
1Q
+
1Y
+
+
+
+
+
+
+
+
+
+
+
+
+ {displayData.length === 0 && (
+
No Data
+ )}
+ {displayData.length > 0 && (
+
+
+
+ Name
+ {baseDate}
+ Difference
+ {headDate}
+
+
+
+ {displayData.map((item, index) => (
+
+ {item.name}
+ {item.base}
+
+ {item.cmp}
+
+ {item.head}
+
+ ))}
+
+
)}
- {data.map((item, index) => (
-
-
- {item.name}
-
-
- {showColumnVal(item, "base")}
-
-
0
- ? "green"
- : "red",
- maxWidth: "200px",
- }}
- title={prettyComparisonResult(item.base, item.head)}
- >
- {prettyComparisonResult(item.base, item.head)}
-
-
- {showColumnVal(item, "head")}
-
-
- ))}
>
);
diff --git a/src/components/comparison/index.css b/src/components/comparison/index.css
deleted file mode 100644
index b9499e7..0000000
--- a/src/components/comparison/index.css
+++ /dev/null
@@ -1,46 +0,0 @@
-.comparison-container {
- width: 80%;
- margin-left: auto;
- margin-right: auto;
- white-space: nowrap;
- font-family: Arial, sans-serif;
-}
-
-.comparison-container .comparison-date-picker {
- height: 50px;
-}
-
-.comparison-container .comparison-date-picker .comparison-date-picker-item {
- display: inline-block;
- width: 50%;
-}
-
-.comparison-container .comparison-row {
- height: 30px;
- margin-bottom: 10px;
- font-size: 14px;
-}
-
-.comparison-container .comparison-row:nth-child(3n + 2) {
- background-color: #e6e6e6;
-}
-
-.comparison-container .comparison-row:last-child {
- margin-bottom: 0;
-}
-
-.comparison-container .comparison-row .comparison-column {
- display: inline-block;
- width: 24%;
- padding: 5px;
- margin-right: 10px;
- border-radius: 5px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- box-sizing: border-box;
-}
-
-.comparison-container .comparison-row .comparison-column:last-child {
- margin-right: 0;
-}
diff --git a/src/utils/currency.ts b/src/utils/currency.ts
index a9b8d8b..5ae65d8 100644
--- a/src/utils/currency.ts
+++ b/src/utils/currency.ts
@@ -13,6 +13,16 @@ export function prettyNumberToLocaleString(value: number) {
})
}
+// keep n digits after decimal point
+// 1 => 1
+// 1.23456 => 1.234
+// 1.23000 => 1.23
+export function prettyNumberKeepNDigitsAfterDecimalPoint(value: number, keep: number) {
+ return Number.isInteger(value)
+ ? "" + value
+ : value.toFixed(keep).replace(/0+$/, "")
+}
+
// pretty to show price, if price >= 1, keep 3 digits after decimal point
export function prettyPriceNumberToLocaleString(value: number) {
if (value >= 1) {