가상투자 메뉴 기능 구현
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
const SEGMENTS = 25;
|
||||
|
||||
interface Props {
|
||||
matchRate: number;
|
||||
}
|
||||
|
||||
const VirtualSignalEqualizer: React.FC<Props> = ({ matchRate }) => {
|
||||
const litCount = useMemo(
|
||||
() => Math.round((Math.min(100, Math.max(0, matchRate)) / 100) * SEGMENTS),
|
||||
[matchRate],
|
||||
);
|
||||
|
||||
const segments = useMemo(() => {
|
||||
const items: Array<{ lit: boolean; tone: 'blue' | 'gold' | 'peak' }> = [];
|
||||
for (let i = 0; i < SEGMENTS; i++) {
|
||||
const lit = i < litCount;
|
||||
if (!lit) {
|
||||
items.push({ lit: false, tone: 'blue' });
|
||||
continue;
|
||||
}
|
||||
if (matchRate >= 100 && i === SEGMENTS - 1) {
|
||||
items.push({ lit: true, tone: 'peak' });
|
||||
} else if (i >= Math.floor(SEGMENTS * 0.55)) {
|
||||
items.push({ lit: true, tone: 'gold' });
|
||||
} else {
|
||||
items.push({ lit: true, tone: 'blue' });
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}, [litCount, matchRate]);
|
||||
|
||||
const ticks = [100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0];
|
||||
|
||||
return (
|
||||
<div className="vtd-sig-eq">
|
||||
<div className="vtd-sig-eq-scale">
|
||||
{ticks.map(t => (
|
||||
<span key={t} className="vtd-sig-eq-tick">{t}%</span>
|
||||
))}
|
||||
</div>
|
||||
<div className="vtd-sig-eq-bar-wrap">
|
||||
<div className="vtd-sig-eq-bar">
|
||||
{segments.map((seg, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={[
|
||||
'vtd-sig-eq-seg',
|
||||
seg.lit ? 'vtd-sig-eq-seg--lit' : '',
|
||||
seg.lit ? `vtd-sig-eq-seg--${seg.tone}` : '',
|
||||
].filter(Boolean).join(' ')}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{matchRate >= 100 && (
|
||||
<div className="vtd-sig-eq-badge">100% MATCH</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default VirtualSignalEqualizer;
|
||||
Reference in New Issue
Block a user