优化日活用户趋势图 - 使用SVG曲线图替代简单线条,添加动画效果和交互功能

This commit is contained in:
AIGC Developer
2025-10-22 09:22:42 +08:00
parent 9298a744d2
commit fb94de28c2

View File

@@ -108,22 +108,51 @@
</div> </div>
</div> </div>
<div class="chart-container"> <div class="chart-container">
<div class="mock-chart"> <div class="line-chart">
<div class="chart-line"></div> <!-- SVG 曲线图 -->
<div class="chart-points"> <svg width="100%" height="200" viewBox="0 0 800 200" class="chart-svg">
<div class="chart-point" style="left: 15%; top: 60%;"></div> <!-- 网格线 -->
<div class="chart-point" style="left: 25%; top: 40%;"></div> <defs>
<div class="chart-point" style="left: 35%; top: 30%;"></div> <pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
<div class="chart-point" style="left: 45%; top: 50%;"></div> <path d="M 40 0 L 0 0 0 40" fill="none" stroke="#e2e8f0" stroke-width="0.5"/>
<div class="chart-point" style="left: 55%; top: 35%;"></div> </pattern>
<div class="chart-point" style="left: 65%; top: 25%;"></div> </defs>
<div class="chart-point" style="left: 75%; top: 45%;"></div> <rect width="100%" height="100%" fill="url(#grid)" />
<div class="chart-point" style="left: 85%; top: 40%;"></div>
</div> <!-- 数据曲线 -->
<div class="chart-tooltip" style="left: 25%; top: 20%;"> <path d="M 60,160 Q 120,140 180,120 T 300,80 T 420,100 T 540,60 T 660,80 T 740,70"
<div class="tooltip-value">1,000</div> fill="none"
<div class="tooltip-date">2月12号</div> stroke="#3b82f6"
</div> stroke-width="3"
class="chart-line-path"/>
<!-- 数据点 -->
<circle cx="60" cy="160" r="4" fill="#3b82f6" class="chart-dot"/>
<circle cx="120" cy="140" r="4" fill="#3b82f6" class="chart-dot"/>
<circle cx="180" cy="120" r="4" fill="#3b82f6" class="chart-dot"/>
<circle cx="240" cy="100" r="4" fill="#3b82f6" class="chart-dot"/>
<circle cx="300" cy="80" r="4" fill="#3b82f6" class="chart-dot"/>
<circle cx="360" cy="90" r="4" fill="#3b82f6" class="chart-dot"/>
<circle cx="420" cy="100" r="4" fill="#3b82f6" class="chart-dot"/>
<circle cx="480" cy="80" r="4" fill="#3b82f6" class="chart-dot"/>
<circle cx="540" cy="60" r="4" fill="#3b82f6" class="chart-dot"/>
<circle cx="600" cy="70" r="4" fill="#3b82f6" class="chart-dot"/>
<circle cx="660" cy="80" r="4" fill="#3b82f6" class="chart-dot"/>
<circle cx="720" cy="70" r="4" fill="#3b82f6" class="chart-dot"/>
<!-- 高亮数据点 -->
<circle cx="300" cy="80" r="6" fill="#3b82f6" class="highlight-dot"/>
<circle cx="300" cy="80" r="12" fill="#3b82f6" opacity="0.2" class="highlight-ring"/>
<!-- 工具提示 -->
<g class="tooltip-group" transform="translate(300, 60)">
<rect x="-30" y="-40" width="60" height="30" rx="6" fill="#1e293b" class="tooltip-bg"/>
<text x="0" y="-25" text-anchor="middle" fill="white" font-size="12" font-weight="600" class="tooltip-value">1,000</text>
<text x="0" y="-10" text-anchor="middle" fill="white" font-size="10" opacity="0.8" class="tooltip-date">2月12号</text>
<!-- 工具提示箭头 -->
<polygon points="0,0 -5,10 5,10" fill="#1e293b" class="tooltip-arrow"/>
</g>
</svg>
</div> </div>
<div class="chart-x-axis"> <div class="chart-x-axis">
<span>1</span> <span>1</span>
@@ -553,78 +582,107 @@ onMounted(() => {
height: 300px; height: 300px;
} }
/* 日活用户趋势图 */ /* 日活用户趋势图 - SVG曲线图 */
.mock-chart { .line-chart {
position: relative; position: relative;
width: 100%; width: 100%;
height: 200px; height: 200px;
margin-bottom: 20px; margin-bottom: 20px;
background: white;
border-radius: 8px;
overflow: hidden;
} }
.chart-line { .chart-svg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
45deg,
transparent 0%,
transparent 15%,
#3b82f6 15%,
#3b82f6 25%,
transparent 25%,
transparent 35%,
#3b82f6 35%,
#3b82f6 45%,
transparent 45%,
transparent 55%,
#3b82f6 55%,
#3b82f6 65%,
transparent 65%,
transparent 75%,
#3b82f6 75%,
#3b82f6 85%,
transparent 85%
);
opacity: 0.3;
}
.chart-points {
position: absolute;
top: 0;
left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.chart-point { .chart-line-path {
position: absolute; stroke-dasharray: 1000;
width: 6px; stroke-dashoffset: 1000;
height: 6px; animation: drawLine 2s ease-in-out forwards;
background: #3b82f6;
border-radius: 50%;
border: 2px solid white;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
} }
.chart-tooltip { .chart-dot {
position: absolute; opacity: 0;
background: #1e293b; animation: fadeInDots 0.5s ease-in-out forwards;
color: white; animation-delay: 1.5s;
padding: 8px 12px;
border-radius: 6px;
font-size: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
} }
.tooltip-value { .highlight-dot {
font-weight: 600; opacity: 0;
margin-bottom: 2px; animation: highlightDot 0.5s ease-in-out forwards;
animation-delay: 2s;
} }
.tooltip-date { .highlight-ring {
opacity: 0.8; opacity: 0;
animation: highlightRing 1s ease-in-out infinite;
animation-delay: 2s;
}
.tooltip-group {
opacity: 0;
animation: fadeInTooltip 0.5s ease-in-out forwards;
animation-delay: 2.5s;
}
.tooltip-bg {
filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.15));
}
.tooltip-arrow {
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
}
/* 动画效果 */
@keyframes drawLine {
to {
stroke-dashoffset: 0;
}
}
@keyframes fadeInDots {
to {
opacity: 1;
}
}
@keyframes highlightDot {
to {
opacity: 1;
}
}
@keyframes highlightRing {
0%, 100% {
opacity: 0.2;
transform: scale(1);
}
50% {
opacity: 0.4;
transform: scale(1.2);
}
}
@keyframes fadeInTooltip {
to {
opacity: 1;
}
}
/* 悬停效果 */
.chart-dot:hover {
r: 6;
fill: #2563eb;
transition: all 0.2s ease;
}
.highlight-dot:hover {
r: 8;
fill: #2563eb;
transition: all 0.2s ease;
} }
.chart-x-axis { .chart-x-axis {