优化日活用户趋势图 - 使用SVG曲线图替代简单线条,添加动画效果和交互功能
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user