Skip to content

Commit f4fed55

Browse files
feat: Implement dynamic precision calculation for the depth chart and enhance Binance market data services.
1 parent 94eb88d commit f4fed55

5 files changed

Lines changed: 239 additions & 81 deletions

File tree

src/components/Dashboard/Chart/DepthChart.tsx

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Canvas + React 混合渲染的币安风格市场深度图
44
*/
55

6-
import { memo, useRef, useEffect, useCallback, useState } from 'react';
6+
import { memo, useRef, useEffect, useCallback, useState, useMemo } from 'react';
77
import { ZoomIn, ZoomOut } from 'lucide-react';
88
import { drawDepthChart, fmtVol } from './depthCanvas';
99
import { useDepthData } from './hooks/useDepthData';
@@ -18,6 +18,41 @@ interface DepthChartProps {
1818
price?: number;
1919
}
2020

21+
/* ============================================
22+
工具函数
23+
============================================ */
24+
25+
/**
26+
* 根据当前价格自动计算合适的深度图聚合精度
27+
* 目标:让深度图可视范围内有约 30~60 个价格档位
28+
*/
29+
function computeAutoPrecision(price: number | undefined): number {
30+
if (!price || price <= 0) return 0.1;
31+
// 取价格量级,然后选择约为价格 0.01% ~ 0.02% 的精度
32+
const magnitude = Math.pow(10, Math.floor(Math.log10(price)));
33+
// 产生的最小步长约为价格的 0.01%
34+
const rawStep = magnitude * 0.0001;
35+
// 对齐到整数量级: 0.01, 0.05, 0.1, 0.5, 1, 5, 10, 50, 100...
36+
const niceSteps = [0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000];
37+
return niceSteps.find(s => s >= rawStep) ?? rawStep;
38+
}
39+
40+
/**
41+
* 根据当前价格生成合理的精度选项列表
42+
*/
43+
function computePrecisionOptions(price: number | undefined): number[] {
44+
if (!price || price <= 0) return [0.01, 0.05, 0.1, 0.5, 1, 5, 10, 50, 100];
45+
const auto = computeAutoPrecision(price);
46+
// 生成 auto 为基准的 5 个档位: auto/10, auto/5, auto, auto*5, auto*10
47+
const candidates = [auto / 10, auto / 5, auto / 2, auto, auto * 2, auto * 5, auto * 10, auto * 50];
48+
// 过滤掉小于 0.01 和重复值,保留合理范围
49+
return [...new Set(candidates.filter(v => v >= 0.01).map(v => {
50+
// 美化数字:避免浮点精度问题
51+
if (v >= 1) return Math.round(v);
52+
return parseFloat(v.toPrecision(2));
53+
}))].sort((a, b) => a - b);
54+
}
55+
2156
/* ============================================
2257
组件
2358
============================================ */
@@ -27,7 +62,14 @@ function DepthChart({ bids, asks, price }: DepthChartProps) {
2762
const containerRef = useRef<HTMLDivElement>(null);
2863
const [size, setSize] = useState({ w: 0, h: 0 });
2964
const [mouse, setMouse] = useState<{ x: number; y: number } | null>(null);
30-
const [precision, setPrecision] = useState(0.1);
65+
66+
// 自动精度:基于价格动态计算
67+
const autoPrecision = useMemo(() => computeAutoPrecision(price), [price]);
68+
const [userPrecision, setUserPrecision] = useState<number | null>(null);
69+
const precision = userPrecision ?? autoPrecision;
70+
71+
// 动态精度选项
72+
const precisionOptions = useMemo(() => computePrecisionOptions(price), [price]);
3173

3274
// 数据处理 Hook
3375
const {
@@ -169,15 +211,15 @@ function DepthChart({ bids, asks, price }: DepthChartProps) {
169211
</button>
170212
</div>
171213

172-
{/* 精度选择 (新增) */}
214+
{/* 精度选择 */}
173215
<div className="absolute top-2 right-3 z-10">
174216
<select
175217
value={precision}
176-
onChange={(e) => setPrecision(Number(e.target.value))}
218+
onChange={(e) => setUserPrecision(Number(e.target.value))}
177219
className="bg-bg-surface/80 backdrop-blur-sm border border-border-dark text-[10px] text-gray-400 rounded px-1.5 py-0.5 outline-none hover:text-white hover:bg-bg-surface-alt transition-colors cursor-pointer appearance-none text-right min-w-[60px]"
178220
title="调整聚合精度"
179221
>
180-
{[0.01, 0.05, 0.1, 0.5, 1, 5, 10, 50, 100].map((p) => (
222+
{precisionOptions.map((p) => (
181223
<option key={p} value={p}>
182224
Step: {p}
183225
</option>
@@ -189,3 +231,4 @@ function DepthChart({ bids, asks, price }: DepthChartProps) {
189231
}
190232

191233
export default memo(DepthChart);
234+

0 commit comments

Comments
 (0)