pref: FundingPanel 黑金主题改造 融资融券面板
This commit is contained in:
@@ -1,12 +1,10 @@
|
|||||||
// src/views/Company/components/MarketDataView/components/panels/FundingPanel.tsx
|
// src/views/Company/components/MarketDataView/components/panels/FundingPanel.tsx
|
||||||
// 融资融券面板 - 融资融券数据图表和卡片
|
// 融资融券面板 - 黑金主题
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Text,
|
Text,
|
||||||
CardBody,
|
|
||||||
CardHeader,
|
|
||||||
VStack,
|
VStack,
|
||||||
HStack,
|
HStack,
|
||||||
Grid,
|
Grid,
|
||||||
@@ -14,9 +12,9 @@ import {
|
|||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import ReactECharts from 'echarts-for-react';
|
import ReactECharts from 'echarts-for-react';
|
||||||
|
|
||||||
import ThemedCard from '../ThemedCard';
|
|
||||||
import { formatNumber } from '../../utils/formatUtils';
|
import { formatNumber } from '../../utils/formatUtils';
|
||||||
import { getFundingOption } from '../../utils/chartOptions';
|
import { getFundingDarkGoldOption } from '../../utils/chartOptions';
|
||||||
|
import { darkGoldTheme } from '../../constants';
|
||||||
import type { Theme, FundingDayData } from '../../types';
|
import type { Theme, FundingDayData } from '../../types';
|
||||||
|
|
||||||
export interface FundingPanelProps {
|
export interface FundingPanelProps {
|
||||||
@@ -24,45 +22,73 @@ export interface FundingPanelProps {
|
|||||||
fundingData: FundingDayData[];
|
fundingData: FundingDayData[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const FundingPanel: React.FC<FundingPanelProps> = ({ theme, fundingData }) => {
|
// 黑金卡片样式
|
||||||
|
const darkGoldCardStyle = {
|
||||||
|
bg: darkGoldTheme.bgCard,
|
||||||
|
border: '1px solid',
|
||||||
|
borderColor: darkGoldTheme.border,
|
||||||
|
borderRadius: 'xl',
|
||||||
|
boxShadow: '0 4px 20px rgba(0, 0, 0, 0.3)',
|
||||||
|
transition: 'all 0.3s ease',
|
||||||
|
_hover: {
|
||||||
|
borderColor: darkGoldTheme.borderHover,
|
||||||
|
boxShadow: '0 8px 30px rgba(212, 175, 55, 0.15)',
|
||||||
|
transform: 'translateY(-2px)',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const FundingPanel: React.FC<FundingPanelProps> = ({ fundingData }) => {
|
||||||
return (
|
return (
|
||||||
<VStack spacing={6} align="stretch">
|
<VStack spacing={6} align="stretch">
|
||||||
<ThemedCard theme={theme}>
|
{/* 图表卡片 */}
|
||||||
<CardBody>
|
<Box {...darkGoldCardStyle} p={6}>
|
||||||
{fundingData.length > 0 && (
|
{fundingData.length > 0 && (
|
||||||
<Box h="400px">
|
<Box h="400px">
|
||||||
<ReactECharts
|
<ReactECharts
|
||||||
option={getFundingOption(theme, fundingData)}
|
option={getFundingDarkGoldOption(fundingData)}
|
||||||
style={{ height: '100%', width: '100%' }}
|
style={{ height: '100%', width: '100%' }}
|
||||||
theme="light"
|
theme="dark"
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</CardBody>
|
</Box>
|
||||||
</ThemedCard>
|
|
||||||
|
|
||||||
<Grid templateColumns="repeat(2, 1fr)" gap={6}>
|
<Grid templateColumns="repeat(2, 1fr)" gap={6}>
|
||||||
{/* 融资数据 */}
|
{/* 融资数据 */}
|
||||||
<ThemedCard theme={theme}>
|
<Box {...darkGoldCardStyle} overflow="hidden">
|
||||||
<CardHeader>
|
<Box p={4} borderBottom="1px solid" borderColor={darkGoldTheme.border}>
|
||||||
<Heading size="md" color={theme.success}>
|
<Heading size="md" color={darkGoldTheme.gold}>
|
||||||
融资数据
|
融资数据
|
||||||
</Heading>
|
</Heading>
|
||||||
</CardHeader>
|
</Box>
|
||||||
<CardBody>
|
<Box p={4}>
|
||||||
<VStack spacing={3} align="stretch">
|
<VStack spacing={3} align="stretch">
|
||||||
{fundingData
|
{fundingData
|
||||||
.slice(-5)
|
.slice(-5)
|
||||||
.reverse()
|
.reverse()
|
||||||
.map((item, idx) => (
|
.map((item, idx) => (
|
||||||
<Box key={idx} p={3} bg="rgba(255, 68, 68, 0.05)" borderRadius="md">
|
<Box
|
||||||
|
key={idx}
|
||||||
|
p={3}
|
||||||
|
bg="rgba(212, 175, 55, 0.08)"
|
||||||
|
borderRadius="md"
|
||||||
|
border="1px solid"
|
||||||
|
borderColor="rgba(212, 175, 55, 0.15)"
|
||||||
|
transition="all 0.2s"
|
||||||
|
_hover={{
|
||||||
|
bg: 'rgba(212, 175, 55, 0.12)',
|
||||||
|
borderColor: 'rgba(212, 175, 55, 0.3)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<HStack justify="space-between">
|
<HStack justify="space-between">
|
||||||
<Text color={theme.textMuted}>{item.date}</Text>
|
<Text color={darkGoldTheme.textMuted} fontSize="sm">
|
||||||
|
{item.date}
|
||||||
|
</Text>
|
||||||
<VStack align="end" spacing={0}>
|
<VStack align="end" spacing={0}>
|
||||||
<Text color={theme.textPrimary} fontWeight="bold">
|
<Text color={darkGoldTheme.gold} fontWeight="bold">
|
||||||
{formatNumber(item.financing.balance)}
|
{formatNumber(item.financing.balance)}
|
||||||
</Text>
|
</Text>
|
||||||
<Text fontSize="xs" color={theme.textMuted}>
|
<Text fontSize="xs" color={darkGoldTheme.textMuted}>
|
||||||
买入{formatNumber(item.financing.buy)} / 偿还
|
买入{formatNumber(item.financing.buy)} / 偿还
|
||||||
{formatNumber(item.financing.repay)}
|
{formatNumber(item.financing.repay)}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -71,30 +97,44 @@ const FundingPanel: React.FC<FundingPanelProps> = ({ theme, fundingData }) => {
|
|||||||
</Box>
|
</Box>
|
||||||
))}
|
))}
|
||||||
</VStack>
|
</VStack>
|
||||||
</CardBody>
|
</Box>
|
||||||
</ThemedCard>
|
</Box>
|
||||||
|
|
||||||
{/* 融券数据 */}
|
{/* 融券数据 */}
|
||||||
<ThemedCard theme={theme}>
|
<Box {...darkGoldCardStyle} overflow="hidden">
|
||||||
<CardHeader>
|
<Box p={4} borderBottom="1px solid" borderColor={darkGoldTheme.border}>
|
||||||
<Heading size="md" color={theme.danger}>
|
<Heading size="md" color={darkGoldTheme.orange}>
|
||||||
融券数据
|
融券数据
|
||||||
</Heading>
|
</Heading>
|
||||||
</CardHeader>
|
</Box>
|
||||||
<CardBody>
|
<Box p={4}>
|
||||||
<VStack spacing={3} align="stretch">
|
<VStack spacing={3} align="stretch">
|
||||||
{fundingData
|
{fundingData
|
||||||
.slice(-5)
|
.slice(-5)
|
||||||
.reverse()
|
.reverse()
|
||||||
.map((item, idx) => (
|
.map((item, idx) => (
|
||||||
<Box key={idx} p={3} bg="rgba(0, 200, 81, 0.05)" borderRadius="md">
|
<Box
|
||||||
|
key={idx}
|
||||||
|
p={3}
|
||||||
|
bg="rgba(255, 149, 0, 0.08)"
|
||||||
|
borderRadius="md"
|
||||||
|
border="1px solid"
|
||||||
|
borderColor="rgba(255, 149, 0, 0.15)"
|
||||||
|
transition="all 0.2s"
|
||||||
|
_hover={{
|
||||||
|
bg: 'rgba(255, 149, 0, 0.12)',
|
||||||
|
borderColor: 'rgba(255, 149, 0, 0.3)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<HStack justify="space-between">
|
<HStack justify="space-between">
|
||||||
<Text color={theme.textMuted}>{item.date}</Text>
|
<Text color={darkGoldTheme.textMuted} fontSize="sm">
|
||||||
|
{item.date}
|
||||||
|
</Text>
|
||||||
<VStack align="end" spacing={0}>
|
<VStack align="end" spacing={0}>
|
||||||
<Text color={theme.textPrimary} fontWeight="bold">
|
<Text color={darkGoldTheme.orange} fontWeight="bold">
|
||||||
{formatNumber(item.securities.balance)}
|
{formatNumber(item.securities.balance)}
|
||||||
</Text>
|
</Text>
|
||||||
<Text fontSize="xs" color={theme.textMuted}>
|
<Text fontSize="xs" color={darkGoldTheme.textMuted}>
|
||||||
卖出{formatNumber(item.securities.sell)} / 偿还
|
卖出{formatNumber(item.securities.sell)} / 偿还
|
||||||
{formatNumber(item.securities.repay)}
|
{formatNumber(item.securities.repay)}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -103,8 +143,8 @@ const FundingPanel: React.FC<FundingPanelProps> = ({ theme, fundingData }) => {
|
|||||||
</Box>
|
</Box>
|
||||||
))}
|
))}
|
||||||
</VStack>
|
</VStack>
|
||||||
</CardBody>
|
</Box>
|
||||||
</ThemedCard>
|
</Box>
|
||||||
</Grid>
|
</Grid>
|
||||||
</VStack>
|
</VStack>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -575,6 +575,154 @@ export const getFundingOption = (theme: Theme, fundingData: FundingDayData[]): E
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成融资融券图表配置 - 黑金主题
|
||||||
|
*/
|
||||||
|
export const getFundingDarkGoldOption = (fundingData: FundingDayData[]): EChartsOption => {
|
||||||
|
if (!fundingData || fundingData.length === 0) return {};
|
||||||
|
|
||||||
|
const dates = fundingData.map((item) => item.date.substring(5, 10));
|
||||||
|
const financing = fundingData.map((item) => item.financing.balance / 100000000);
|
||||||
|
const securities = fundingData.map((item) => item.securities.balance_amount / 100000000);
|
||||||
|
|
||||||
|
// 黑金主题色
|
||||||
|
const gold = '#D4AF37';
|
||||||
|
const goldLight = '#F4D03F';
|
||||||
|
const textColor = 'rgba(255, 255, 255, 0.85)';
|
||||||
|
const textMuted = 'rgba(255, 255, 255, 0.5)';
|
||||||
|
const borderColor = 'rgba(212, 175, 55, 0.2)';
|
||||||
|
|
||||||
|
return {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
title: {
|
||||||
|
text: '融资融券余额走势',
|
||||||
|
left: 'center',
|
||||||
|
textStyle: {
|
||||||
|
color: gold,
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
backgroundColor: 'rgba(26, 26, 46, 0.95)',
|
||||||
|
borderColor: gold,
|
||||||
|
borderWidth: 1,
|
||||||
|
textStyle: {
|
||||||
|
color: textColor,
|
||||||
|
},
|
||||||
|
formatter: (params: unknown) => {
|
||||||
|
const paramsArr = params as { name: string; marker: string; seriesName: string; value: number }[];
|
||||||
|
let result = `<span style="color: ${gold}">${paramsArr[0].name}</span><br/>`;
|
||||||
|
paramsArr.forEach((param) => {
|
||||||
|
result += `${param.marker} ${param.seriesName}: <span style="color: ${goldLight}; font-weight: bold">${param.value.toFixed(2)}亿</span><br/>`;
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ['融资余额', '融券余额'],
|
||||||
|
bottom: 10,
|
||||||
|
textStyle: {
|
||||||
|
color: textColor,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '3%',
|
||||||
|
right: '4%',
|
||||||
|
bottom: '15%',
|
||||||
|
containLabel: true,
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: false,
|
||||||
|
data: dates,
|
||||||
|
axisLine: { lineStyle: { color: borderColor } },
|
||||||
|
axisLabel: { color: textMuted },
|
||||||
|
splitLine: { show: false },
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
name: '金额(亿)',
|
||||||
|
nameTextStyle: { color: textMuted },
|
||||||
|
splitLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: borderColor,
|
||||||
|
type: 'dashed',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisLine: { lineStyle: { color: borderColor } },
|
||||||
|
axisLabel: { color: textMuted },
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '融资余额',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
symbol: 'circle',
|
||||||
|
symbolSize: 8,
|
||||||
|
areaStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: 'rgba(212, 175, 55, 0.4)' },
|
||||||
|
{ offset: 1, color: 'rgba(212, 175, 55, 0.05)' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
color: gold,
|
||||||
|
width: 2,
|
||||||
|
shadowBlur: 10,
|
||||||
|
shadowColor: 'rgba(212, 175, 55, 0.5)',
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: gold,
|
||||||
|
borderColor: goldLight,
|
||||||
|
borderWidth: 2,
|
||||||
|
},
|
||||||
|
data: financing,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '融券余额',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
symbol: 'diamond',
|
||||||
|
symbolSize: 8,
|
||||||
|
areaStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: 'rgba(255, 149, 0, 0.4)' },
|
||||||
|
{ offset: 1, color: 'rgba(255, 149, 0, 0.05)' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
color: '#FF9500',
|
||||||
|
width: 2,
|
||||||
|
shadowBlur: 10,
|
||||||
|
shadowColor: 'rgba(255, 149, 0, 0.5)',
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: '#FF9500',
|
||||||
|
borderColor: '#FFB347',
|
||||||
|
borderWidth: 2,
|
||||||
|
},
|
||||||
|
data: securities,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成股权质押图表配置
|
* 生成股权质押图表配置
|
||||||
*/
|
*/
|
||||||
@@ -694,5 +842,6 @@ export default {
|
|||||||
getKLineOption,
|
getKLineOption,
|
||||||
getMinuteKLineOption,
|
getMinuteKLineOption,
|
||||||
getFundingOption,
|
getFundingOption,
|
||||||
|
getFundingDarkGoldOption,
|
||||||
getPledgeOption,
|
getPledgeOption,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user