优化日活用户趋势图 - 使用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 class="chart-container">
<div class="mock-chart">
<div class="chart-line"></div>
<div class="chart-points">
<div class="chart-point" style="left: 15%; top: 60%;"></div>
<div class="chart-point" style="left: 25%; top: 40%;"></div>
<div class="chart-point" style="left: 35%; top: 30%;"></div>
<div class="chart-point" style="left: 45%; top: 50%;"></div>
<div class="chart-point" style="left: 55%; top: 35%;"></div>
<div class="chart-point" style="left: 65%; top: 25%;"></div>
<div class="chart-point" style="left: 75%; top: 45%;"></div>
<div class="chart-point" style="left: 85%; top: 40%;"></div>
</div>
<div class="chart-tooltip" style="left: 25%; top: 20%;">
<div class="tooltip-value">1,000</div>
<div class="tooltip-date">2月12号</div>
</div>
<div class="line-chart">
<!-- SVG 曲线图 -->
<svg width="100%" height="200" viewBox="0 0 800 200" class="chart-svg">
<!-- 网格线 -->
<defs>
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="#e2e8f0" stroke-width="0.5"/>
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#grid)" />
<!-- 数据曲线 -->
<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"
fill="none"
stroke="#3b82f6"
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 class="chart-x-axis">
<span>1</span>
@@ -553,78 +582,107 @@ onMounted(() => {
height: 300px;
}
/* 日活用户趋势图 */
.mock-chart {
/* 日活用户趋势图 - SVG曲线图 */
.line-chart {
position: relative;
width: 100%;
height: 200px;
margin-bottom: 20px;
background: white;
border-radius: 8px;
overflow: hidden;
}
.chart-line {
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;
.chart-svg {
width: 100%;
height: 100%;
}
.chart-point {
position: absolute;
width: 6px;
height: 6px;
background: #3b82f6;
border-radius: 50%;
border: 2px solid white;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
.chart-line-path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: drawLine 2s ease-in-out forwards;
}
.chart-tooltip {
position: absolute;
background: #1e293b;
color: white;
padding: 8px 12px;
border-radius: 6px;
font-size: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
.chart-dot {
opacity: 0;
animation: fadeInDots 0.5s ease-in-out forwards;
animation-delay: 1.5s;
}
.tooltip-value {
font-weight: 600;
margin-bottom: 2px;
.highlight-dot {
opacity: 0;
animation: highlightDot 0.5s ease-in-out forwards;
animation-delay: 2s;
}
.tooltip-date {
opacity: 0.8;
.highlight-ring {
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 {