heropanel修改
This commit is contained in:
13
app.py
13
app.py
@@ -11306,7 +11306,10 @@ def get_events_effectiveness_stats():
|
||||
if prev_trading_day:
|
||||
prev_date_str = prev_trading_day.strftime('%Y%m%d')
|
||||
|
||||
# 查询所有 A 股的最新价格(排除指数和北交所)
|
||||
# 查询所有 A 股的最新价格(排除指数)
|
||||
# 上证股票: 60xxxx.SH (主板), 68xxxx.SH (科创板)
|
||||
# 深证股票: 00xxxx.SZ (主板), 30xxxx.SZ (创业板)
|
||||
# 排除: 399xxx.SZ (深证指数), 000xxx.SH (上证指数)
|
||||
market_price_query = """
|
||||
SELECT
|
||||
code,
|
||||
@@ -11314,9 +11317,11 @@ def get_events_effectiveness_stats():
|
||||
FROM stock_minute
|
||||
WHERE timestamp >= %(start)s
|
||||
AND timestamp <= %(end)s
|
||||
AND (code LIKE '%%.SH' OR code LIKE '%%.SZ')
|
||||
AND code NOT LIKE '399%%'
|
||||
AND code NOT LIKE '000%%'
|
||||
AND (
|
||||
(code LIKE '6%%.SH') -- 上证主板和科创板
|
||||
OR (code LIKE '0%%.SZ' AND code NOT LIKE '399%%') -- 深证主板(排除指数)
|
||||
OR (code LIKE '3%%.SZ' AND code NOT LIKE '399%%') -- 创业板(排除指数)
|
||||
)
|
||||
GROUP BY code
|
||||
"""
|
||||
market_data = client.execute(market_price_query, {
|
||||
|
||||
@@ -69,8 +69,8 @@ const getRateColor = (rate) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* 半圆仪表盘组件 - 参考用户提供的设计
|
||||
* 使用渐变色:左侧绿色 -> 中间黄色 -> 右侧红色
|
||||
* 半圆仪表盘组件 - 使用 SVG 实现渐变弧线
|
||||
* 渐变色:左侧绿色 -> 中间黄色 -> 右侧红色
|
||||
*/
|
||||
const SemiCircleGauge = ({ rate, label, size = 'normal' }) => {
|
||||
const validRate = Math.min(100, Math.max(0, rate || 0));
|
||||
@@ -79,57 +79,43 @@ const SemiCircleGauge = ({ rate, label, size = 'normal' }) => {
|
||||
|
||||
const gaugeColor = getRateColor(validRate);
|
||||
const isSmall = size === 'small';
|
||||
const gaugeWidth = isSmall ? 80 : 100;
|
||||
const gaugeHeight = gaugeWidth / 2;
|
||||
const needleLength = isSmall ? 30 : 38;
|
||||
const svgSize = isSmall ? 80 : 100;
|
||||
const strokeWidth = isSmall ? 6 : 8;
|
||||
const radius = (svgSize - strokeWidth) / 2;
|
||||
const needleLength = isSmall ? 28 : 35;
|
||||
const gradientId = `gauge-gradient-${label.replace(/\s/g, '-')}`;
|
||||
|
||||
// 计算半圆弧的路径(从左到右)
|
||||
const arcPath = `M ${strokeWidth / 2} ${svgSize / 2} A ${radius} ${radius} 0 0 1 ${svgSize - strokeWidth / 2} ${svgSize / 2}`;
|
||||
|
||||
return (
|
||||
<Box position="relative" w={`${gaugeWidth}px`} h={`${gaugeHeight + 20}px`}>
|
||||
{/* 半圆背景(渐变色弧线) */}
|
||||
<Box
|
||||
position="absolute"
|
||||
bottom="16px"
|
||||
left="0"
|
||||
w={`${gaugeWidth}px`}
|
||||
h={`${gaugeHeight}px`}
|
||||
borderTopLeftRadius={`${gaugeHeight}px`}
|
||||
borderTopRightRadius={`${gaugeHeight}px`}
|
||||
bg="transparent"
|
||||
overflow="hidden"
|
||||
_before={{
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
top: '0',
|
||||
left: '0',
|
||||
right: '0',
|
||||
bottom: '0',
|
||||
borderTopLeftRadius: `${gaugeHeight}px`,
|
||||
borderTopRightRadius: `${gaugeHeight}px`,
|
||||
border: `${isSmall ? '6px' : '8px'} solid transparent`,
|
||||
borderBottom: 'none',
|
||||
background: 'linear-gradient(90deg, #52C41A 0%, #FADB14 50%, #FF4D4F 100%) border-box',
|
||||
mask: 'linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0)',
|
||||
maskComposite: 'exclude',
|
||||
WebkitMaskComposite: 'destination-out',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 内部遮罩(让弧线更细) */}
|
||||
<Box
|
||||
position="absolute"
|
||||
bottom="16px"
|
||||
left={`${isSmall ? 10 : 12}px`}
|
||||
w={`${gaugeWidth - (isSmall ? 20 : 24)}px`}
|
||||
h={`${gaugeHeight - (isSmall ? 10 : 12)}px`}
|
||||
borderTopLeftRadius={`${gaugeHeight - (isSmall ? 10 : 12)}px`}
|
||||
borderTopRightRadius={`${gaugeHeight - (isSmall ? 10 : 12)}px`}
|
||||
bg="rgba(17, 24, 39, 0.95)"
|
||||
/>
|
||||
<Box position="relative" w={`${svgSize}px`} h={`${svgSize / 2 + 18}px`}>
|
||||
{/* SVG 半圆弧 */}
|
||||
<svg
|
||||
width={svgSize}
|
||||
height={svgSize / 2 + 2}
|
||||
style={{ position: 'absolute', top: 0, left: 0 }}
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id={gradientId} x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stopColor="#52C41A" />
|
||||
<stop offset="50%" stopColor="#FADB14" />
|
||||
<stop offset="100%" stopColor="#FF4D4F" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
d={arcPath}
|
||||
fill="none"
|
||||
stroke={`url(#${gradientId})`}
|
||||
strokeWidth={strokeWidth}
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
{/* 指针 */}
|
||||
<Box
|
||||
position="absolute"
|
||||
bottom="16px"
|
||||
bottom="18px"
|
||||
left="50%"
|
||||
w="2px"
|
||||
h={`${needleLength}px`}
|
||||
@@ -144,7 +130,7 @@ const SemiCircleGauge = ({ rate, label, size = 'normal' }) => {
|
||||
{/* 指针中心点 */}
|
||||
<Box
|
||||
position="absolute"
|
||||
bottom="13px"
|
||||
bottom="15px"
|
||||
left="50%"
|
||||
transform="translateX(-50%)"
|
||||
w="6px"
|
||||
@@ -157,21 +143,19 @@ const SemiCircleGauge = ({ rate, label, size = 'normal' }) => {
|
||||
{/* 刻度标记 */}
|
||||
<Text
|
||||
position="absolute"
|
||||
bottom="16px"
|
||||
left="0"
|
||||
bottom="18px"
|
||||
left="2px"
|
||||
fontSize="2xs"
|
||||
color="gray.600"
|
||||
transform="translateX(2px)"
|
||||
>
|
||||
0
|
||||
</Text>
|
||||
<Text
|
||||
position="absolute"
|
||||
bottom="16px"
|
||||
right="0"
|
||||
bottom="18px"
|
||||
right="2px"
|
||||
fontSize="2xs"
|
||||
color="gray.600"
|
||||
transform="translateX(-2px)"
|
||||
>
|
||||
100
|
||||
</Text>
|
||||
|
||||
Reference in New Issue
Block a user