299 lines
6.7 KiB
Vue
299 lines
6.7 KiB
Vue
|
|
<template>
|
||
|
|
<!-- Main container -->
|
||
|
|
<div class="leader-ansys">
|
||
|
|
<!-- Background SVG provided by the user -->
|
||
|
|
<div class="bg-svg">
|
||
|
|
<svg
|
||
|
|
width="100%"
|
||
|
|
height="100%"
|
||
|
|
viewBox="0 0 352 542"
|
||
|
|
fill="none"
|
||
|
|
preserveAspectRatio="none"
|
||
|
|
xmlns="http://www.w3.org/2000/svg"
|
||
|
|
>
|
||
|
|
<path
|
||
|
|
d="M350 0.5H2C1.17157 0.5 0.500008 1.17157 0.5 2V540C0.5 540.828 1.17156 541.5 2 541.5H350C350.828 541.5 351.5 540.828 351.5 540V2C351.5 1.17157 350.828 0.5 350 0.5Z"
|
||
|
|
fill="url(#paint0_linear_845_47161)"
|
||
|
|
fill-opacity="0.48"
|
||
|
|
stroke="url(#paint1_linear_845_47161)"
|
||
|
|
/>
|
||
|
|
<defs>
|
||
|
|
<linearGradient
|
||
|
|
id="paint0_linear_845_47161"
|
||
|
|
x1="-1.82995e-07"
|
||
|
|
y1="167.719"
|
||
|
|
x2="352"
|
||
|
|
y2="167.719"
|
||
|
|
gradientUnits="userSpaceOnUse"
|
||
|
|
>
|
||
|
|
<stop stop-color="#063D71" stop-opacity="0.2" />
|
||
|
|
<stop offset="1" stop-color="#081E38" stop-opacity="0.8" />
|
||
|
|
</linearGradient>
|
||
|
|
<linearGradient
|
||
|
|
id="paint1_linear_845_47161"
|
||
|
|
x1="176"
|
||
|
|
y1="0"
|
||
|
|
x2="176"
|
||
|
|
y2="542"
|
||
|
|
gradientUnits="userSpaceOnUse"
|
||
|
|
>
|
||
|
|
<stop stop-color="#3AA1F8" />
|
||
|
|
<stop offset="1" stop-color="#3AA1F8" stop-opacity="0.2" />
|
||
|
|
</linearGradient>
|
||
|
|
</defs>
|
||
|
|
</svg>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Content Area -->
|
||
|
|
<div class="content">
|
||
|
|
<!-- Title Image: using a placeholder as the local asset is not available -->
|
||
|
|
<img
|
||
|
|
src="../../../assets/images/chuanbo-show-title.png"
|
||
|
|
class="title-img"
|
||
|
|
style="margin-top: -22px; margin-left: -24px"
|
||
|
|
/>
|
||
|
|
|
||
|
|
<!-- Charts Wrapper -->
|
||
|
|
<div class="charts-wrapper">
|
||
|
|
<div v-for="chart in chartData" :key="chart.id" class="chart-section">
|
||
|
|
<!-- Section Title -->
|
||
|
|
<div class="section-title">
|
||
|
|
<span class="icon"></span>
|
||
|
|
<span>{{ chart.title }}</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Chart Layout -->
|
||
|
|
<div class="chart-layout">
|
||
|
|
<!-- Y-Axis Labels -->
|
||
|
|
<div class="y-axis-labels">
|
||
|
|
<span v-for="(row, index) in chart.rows" :key="index">{{ row.label }}</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Main Chart Area (Gridlines, Bars, X-Axis) -->
|
||
|
|
<div class="chart-main">
|
||
|
|
<!-- Grid Lines -->
|
||
|
|
<div class="grid-lines">
|
||
|
|
<div v-for="n in 5" :key="n" class="line"></div>
|
||
|
|
</div>
|
||
|
|
<!-- Bars -->
|
||
|
|
<div class="bars">
|
||
|
|
<div v-for="(row, index) in chart.rows" :key="index" class="bar-container">
|
||
|
|
<div
|
||
|
|
class="bar"
|
||
|
|
:class="row.type"
|
||
|
|
:style="{ width: (row.value / chart.max) * 100 + '%' }"
|
||
|
|
></div>
|
||
|
|
<span class="value" :class="{ highlight: row.highlight }">{{ row.value }}</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<!-- X-Axis Labels -->
|
||
|
|
<div class="x-axis-labels">
|
||
|
|
<span v-for="n in 6" :key="n">{{ ((chart.max / 5) * (n - 1)).toFixed(0) }}</span>
|
||
|
|
<span class="unit">{{ chart.unit }}</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup>
|
||
|
|
import { ref } from "vue";
|
||
|
|
|
||
|
|
const chartData = ref([
|
||
|
|
{
|
||
|
|
id: 1,
|
||
|
|
title: "平均发帖数",
|
||
|
|
unit: "数量",
|
||
|
|
max: 20,
|
||
|
|
rows: [
|
||
|
|
{ label: "桥梁节点", value: 14.4, type: "leader" },
|
||
|
|
{ label: "其他节点", value: 5.2, type: "user" }
|
||
|
|
]
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 2,
|
||
|
|
title: "帖子平均生存周期",
|
||
|
|
unit: "分钟",
|
||
|
|
max: 40,
|
||
|
|
rows: [
|
||
|
|
{ label: "桥梁节点", value: (2245.87 / 60).toFixed(2), type: "leader" },
|
||
|
|
{ label: "其他节点", value: (67.43 / 60).toFixed(2), type: "user" }
|
||
|
|
]
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 3,
|
||
|
|
title: "平均粉丝数",
|
||
|
|
unit: "数量",
|
||
|
|
max: 1200,
|
||
|
|
rows: [
|
||
|
|
{ label: "桥梁节点", value: 1033, type: "leader", highlight: false },
|
||
|
|
{ label: "其他节点", value: 120, type: "user" }
|
||
|
|
]
|
||
|
|
}
|
||
|
|
]);
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped>
|
||
|
|
.leader-ansys {
|
||
|
|
position: relative;
|
||
|
|
width: 372px;
|
||
|
|
height: 542px;
|
||
|
|
background-color: #04142166;
|
||
|
|
border-radius: 2px;
|
||
|
|
box-shadow: 0px 0px 18px 0px #0a2e55 inset;
|
||
|
|
backdrop-filter: blur(4px);
|
||
|
|
color: #fff;
|
||
|
|
font-family:
|
||
|
|
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||
|
|
overflow: hidden;
|
||
|
|
box-sizing: border-box;
|
||
|
|
}
|
||
|
|
|
||
|
|
.bg-svg {
|
||
|
|
position: absolute;
|
||
|
|
top: 0;
|
||
|
|
left: 0;
|
||
|
|
width: 100%;
|
||
|
|
height: 100%;
|
||
|
|
z-index: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.content {
|
||
|
|
position: relative;
|
||
|
|
z-index: 1;
|
||
|
|
padding: 15px 25px;
|
||
|
|
height: 100%;
|
||
|
|
box-sizing: border-box;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
}
|
||
|
|
|
||
|
|
.title-img {
|
||
|
|
display: block;
|
||
|
|
margin: 0 auto;
|
||
|
|
}
|
||
|
|
|
||
|
|
.charts-wrapper {
|
||
|
|
margin-top: 24px;
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
gap: 20px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.section-title {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
margin-bottom: 16px;
|
||
|
|
font-size: 16px;
|
||
|
|
color: #e0e0e0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.section-title .icon {
|
||
|
|
width: 8px;
|
||
|
|
height: 8px;
|
||
|
|
background-color: #3aa1f8;
|
||
|
|
margin-right: 8px;
|
||
|
|
flex-shrink: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.chart-layout {
|
||
|
|
display: flex;
|
||
|
|
}
|
||
|
|
|
||
|
|
.y-axis-labels {
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
justify-content: space-around;
|
||
|
|
padding-right: 15px;
|
||
|
|
font-size: 14px;
|
||
|
|
color: #a9c2e1;
|
||
|
|
text-align: right;
|
||
|
|
height: 70px;
|
||
|
|
flex-shrink: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.chart-main {
|
||
|
|
flex: 1;
|
||
|
|
position: relative;
|
||
|
|
}
|
||
|
|
|
||
|
|
.grid-lines {
|
||
|
|
position: absolute;
|
||
|
|
top: 0;
|
||
|
|
left: 0;
|
||
|
|
right: 0;
|
||
|
|
height: 70px; /* Match Y-axis height */
|
||
|
|
display: flex;
|
||
|
|
justify-content: space-between;
|
||
|
|
}
|
||
|
|
.grid-lines .line {
|
||
|
|
width: 1px;
|
||
|
|
height: 100%;
|
||
|
|
border-left: 1px dotted rgba(58, 90, 142, 0.5);
|
||
|
|
}
|
||
|
|
.grid-lines .line:first-child,
|
||
|
|
.grid-lines .line:last-child {
|
||
|
|
display: none;
|
||
|
|
}
|
||
|
|
|
||
|
|
.bars {
|
||
|
|
position: relative;
|
||
|
|
z-index: 2;
|
||
|
|
height: 70px; /* Match Y-axis height */
|
||
|
|
display: flex;
|
||
|
|
flex-direction: column;
|
||
|
|
justify-content: space-around;
|
||
|
|
}
|
||
|
|
|
||
|
|
.bar-container {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
}
|
||
|
|
|
||
|
|
.bar {
|
||
|
|
height: 10px;
|
||
|
|
border-radius: 5px;
|
||
|
|
transition: width 0.5s ease-out;
|
||
|
|
}
|
||
|
|
|
||
|
|
.bar.leader {
|
||
|
|
background: linear-gradient(90deg, #2e7cfb 0%, #3adbf3 100%);
|
||
|
|
}
|
||
|
|
|
||
|
|
.bar.user {
|
||
|
|
background: linear-gradient(90deg, #07bdb8 0%, #3adbf3 100%);
|
||
|
|
}
|
||
|
|
|
||
|
|
.value {
|
||
|
|
margin-left: 8px;
|
||
|
|
font-size: 14px;
|
||
|
|
color: #ffffff;
|
||
|
|
white-space: nowrap;
|
||
|
|
font-size: 20px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.value.highlight {
|
||
|
|
background-color: #d65050;
|
||
|
|
padding: 2px 5px;
|
||
|
|
border-radius: 3px;
|
||
|
|
font-size: 12px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.x-axis-labels {
|
||
|
|
margin-top: 8px;
|
||
|
|
display: flex;
|
||
|
|
justify-content: space-between;
|
||
|
|
font-size: 12px;
|
||
|
|
color: rgba(169, 194, 225, 0.7);
|
||
|
|
position: relative;
|
||
|
|
}
|
||
|
|
.x-axis-labels .unit {
|
||
|
|
position: absolute;
|
||
|
|
right: -25px;
|
||
|
|
top: 0;
|
||
|
|
}
|
||
|
|
</style>
|