164 lines
4.1 KiB
Vue
164 lines
4.1 KiB
Vue
<template>
|
||
<div class="userChart-component">
|
||
<img :src="title" alt="" class="title" />
|
||
<div class="userChart-container">
|
||
<div class="baseLine-back">
|
||
<div class="baseline" v-for="(item, index) in baseLineList" :key="index">
|
||
<div class="baseline-head-number">{{ item }}</div>
|
||
<div class="measure-column-line"></div>
|
||
</div>
|
||
</div>
|
||
<div class="interaction-list">
|
||
<div class="interaction-item" v-for="item in userChartList" :key="item.id">
|
||
<div class="avatar-list">
|
||
<img
|
||
class="avatar-item"
|
||
v-for="child in item.group"
|
||
:key="child.id"
|
||
:src="child.avatar"
|
||
:style="specialHandle(item.group.length)"
|
||
/>
|
||
</div>
|
||
<div class="proportion-line-item">
|
||
<div class="proportion-line">
|
||
<div
|
||
class="reality-ratio-line"
|
||
:style="`width: ${(item.number / baseLineList[baseLineList.length - 2]) * 100 - 9}%`"
|
||
>
|
||
<div class="ratio">{{ item.number }}</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { defineProps, computed } from "vue";
|
||
const baseLineList = [0, 0.2, 0.4, 0.6, 0.8, 1, "数量"];
|
||
const props = defineProps({
|
||
title: {
|
||
type: String,
|
||
default: ""
|
||
},
|
||
userChartList: {
|
||
type: Array,
|
||
default: []
|
||
}
|
||
});
|
||
|
||
const specialHandle = computed(() => {
|
||
return (length) => {
|
||
if (length > 2) {
|
||
return {
|
||
width: "25px",
|
||
height: "25px",
|
||
marginRight: "3px"
|
||
};
|
||
}
|
||
};
|
||
});
|
||
</script>
|
||
|
||
<style scoped lang="less">
|
||
.userChart-component {
|
||
width: 100%;
|
||
height: 100%;
|
||
.title {
|
||
margin-top: -8px;
|
||
margin-left: -2px;
|
||
}
|
||
.userChart-container {
|
||
padding: 0px 20px;
|
||
|
||
.baseLine-back {
|
||
width: 218px;
|
||
display: flex;
|
||
position: relative;
|
||
left: 93px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
top: 17px;
|
||
.baseline {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
.baseline-head-number {
|
||
font-family: D-DIN;
|
||
font-size: 12px;
|
||
color: #94c1ec;
|
||
}
|
||
.measure-column-line {
|
||
position: absolute;
|
||
height: 170px;
|
||
width: 1px; /* 不建议 0.5px,兼容性差 */
|
||
background-image: repeating-linear-gradient(
|
||
to bottom,
|
||
rgba(57, 69, 106, 0.86) 0,
|
||
rgba(57, 69, 106, 0.86) 4px,
|
||
/* 实线段长度 */ transparent 4px,
|
||
transparent 8px /* 4+4=8px 为一个周期 */
|
||
);
|
||
top: 25px;
|
||
}
|
||
}
|
||
}
|
||
.interaction-list {
|
||
.interaction-item {
|
||
width: 100%;
|
||
height: 30px;
|
||
margin: 30px 0;
|
||
display: flex;
|
||
align-items: center;
|
||
.avatar-list {
|
||
display: flex;
|
||
justify-content: flex-start;
|
||
.avatar-item {
|
||
width: 32px;
|
||
height: 32px;
|
||
margin-right: 10px;
|
||
border-radius: 4px;
|
||
}
|
||
}
|
||
|
||
.proportion-line-item {
|
||
width: 100%;
|
||
height: 50px;
|
||
margin-left: 38px;
|
||
overflow: hidden;
|
||
display: flex;
|
||
align-items: center;
|
||
.proportion-line {
|
||
width: 95%;
|
||
background-color: #1b2c3e;
|
||
height: 8px;
|
||
border-radius: 10px;
|
||
.reality-ratio-line {
|
||
width: 70px;
|
||
height: 100%;
|
||
background: linear-gradient(90deg, #2e7cfb 0%, #3adbf3 100%);
|
||
border-radius: 10px;
|
||
position: relative;
|
||
|
||
.ratio {
|
||
color: #2ab8fd;
|
||
font-family: D-DIN;
|
||
font-size: 16px;
|
||
font-style: normal;
|
||
font-weight: 700;
|
||
line-height: normal;
|
||
position: absolute;
|
||
right: -40px;
|
||
top: -10px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|