Files
tra-app/src/pages/course/components/chartThree.vue
T
2025-09-17 09:29:08 +08:00

263 lines
6.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="chart-box">
<view class="cont-box">
<view class="total-line total-line1"></view>
<view class="total-line total-line2"></view>
<view class="total-line total-line3"></view>
<view v-for="width in 3" :class="`percent-${width * 25}`"></view>
<view class="data-box">
<view class="line-box">
<view v-for="width in 3" :class="`percent-${width * 25}`"></view>
</view>
</view>
</view>
<view class="title">
<image class="title-icon" src="@/static/images/course/edit.png" alt=""> </image>
改进建议
</view>
<view class="total-score">
<view class="score-num">{{props.score}}</view>
<image class="total-score-icon" src="@/static/images/course/score.png" alt="" ></image>
</view>
<view v-for="item,index in props.dataList" :class="['score-item', 'score-item'+(index+1)]">
<view class="score-item-name">{{ item.gradeDimensName || item.gradeDimens }}</view>
<view class="score-item-score">{{ item.anlyGrade }}</view>
</view>
</view>
</template>
<script setup>
import { ref, computed} from "vue"
const props = defineProps({
dataList:{
default:() => [],
type: Array
},
score:{
default: 0,
type: [Number,String]
},
size:{
default: 262,
type: [Number,String]
}
})
const dataValue = computed(() => {
return props.dataList.map(t=>t.anlyGrade)
})
let _scale = .9
const chartWidth = computed(() => props.size / _scale + 'rpx')
const chartHeight = computed(() => props.size / _scale + 'rpx')
const scoreMarginX = computed(() => {
return (props.size/2 + 20) + 'rpx'
})
const scoreMarginAbsY = computed(() => {
return '-' + (props.size/2 - 40) + 'rpx'
})
const scoreMarginPercentY = computed(() => {
let score = dataValue.value
return setPercent(80, Math.round(100 * 1.732 / 6 * _scale * 100)/100) + '%'
})
const styleFour = computed(()=>{
// let _blank = (50 - Math.round(100 * 1.732 / 3))/2
// let _margin = _blank +
let _tx = 50
let _ty = 50 - Math.round(100 * 1.732 / 3)* _scale
let _rx = 50 + 50 *_scale
let _ry = 50 + Math.round(100 * 1.732 / 6)* _scale
let _bx = 50 - 50 *_scale
let _by = 50 + Math.round(100 * 1.732 / 6)* _scale
return `polygon(${_tx}% ${_ty}%, ${_rx}% ${_ry}%, ${_bx}% ${_by}%)`
})
const styleFourResult = computed(()=>{
let score = dataValue.value
if(score.length >= 3){
let _tx = 50
let _ty = 50 - setPercent(score[0], Math.round(100 * 1.732 / 3 * _scale * 100)/100)
let _rx = 50 + setPercent(score[1], Math.round(50 *_scale * 100)/100)
let _ry = 50 + setPercent(score[1], Math.round(100 * 1.732 / 6 * _scale * 100)/100)
let _bx = 50 - setPercent(score[2], Math.round(50 *_scale * 100)/100)
let _by = 50 + setPercent(score[2], Math.round(100 * 1.732 / 6 * _scale * 100)/100)
return `polygon(${_tx}% ${_ty}%, ${_rx}% ${_ry}%, ${_bx}% ${_by}%)`
}else{
return styleFour.value
}
})
const setPercent = (precent, show) => {
return Math.floor((precent/100) * show)
}
</script>
<style lang="scss" scoped>
.chart-box{
width: 100%;
height: 580rpx;
background:linear-gradient( 270deg, #4a74ff 0%, #6fa7fe 100%);
overflow: hidden;
position: relative;
border-radius: 16rpx;
margin-bottom: 20rpx;
.cont-box{
background-color: #87abfe;
width: v-bind(chartWidth);
height: v-bind(chartHeight);
clip-path: v-bind(styleFour);
position: absolute;
top: calc(60% + 20rpx);
left: 50%;
transform: translate(-50%, -50%);
.total-line{
width: 57.7%;
height: 3rpx;
background-color: rgba(255, 255, 255, .3);
position: absolute;
overflow: hidden;
z-index: 20;
&.total-line1{
top: 64.5%;
left: 46.5%;
transform: rotateZ(30deg);
}
&.total-line2{
top: 64.5%;
left:-4.5%;
transform: rotateZ(150deg);
}
&.total-line3{
top: 21.5%;
left: 21%;
transform: rotateZ(-90deg);
}
}
@for $i from 1 through 3 {
.percent-#{$i*25}{
width: $i * 25%;
height: $i * 25%;
clip-path: v-bind(styleFour);
background-color: rgba(255, 255, 255, .3);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: (4 - $i) * 2;
&::before{
content: '';
display: block;
width: calc(100% - 10rpx);
height: calc(100% - 10rpx);
background-color: #87abfe;
clip-path: v-bind(styleFour);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
}
.data-box{
width: 100%;
height: 100%;
clip-path: v-bind(styleFourResult);
position: absolute;
background-color: #fff;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 12;
overflow: hidden;
.line-box{
display: block;
width: calc(100% - 24rpx);
height: calc(100% - 24rpx);
// background-color: #6691fe;
background-color: #6691fe;
clip-path: v-bind(styleFourResult);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 14;
}
@for $i from 1 through 3 {
.percent-#{$i*25}{
background-color: rgba(255, 255, 255, .1);
z-index: (4 - $i) * 2 + 10;
&::before{
background-color: #6692ff;
}
}
}
}
}
.title{
padding: 24rpx;
line-height: 46rpx;
font-size: 32rpx;
color: #fff;
.title-icon{
width: 27rpx;
height: 27rpx;
}
}
.total-score{
position: absolute;
right: 30rpx;
top:30rpx;
width: 100rpx;
height: 80rpx;
line-height: 70rpx;
font-size: 30rpx;
color: #fff;
white-space: nowrap;
text-shadow: 0 4px 12px rgba(0, 0, 0, .33);
.score-num{
display: inline-block;
font-size: 60rpx;
line-height: 70rpx;
font-weight: bold;
}
.total-score-icon{
width: 100%;
height: 16rpx;
position: absolute;
bottom:0;
left:0;
}
}
.score-item{
position: absolute;
color: #fff;
width: 120rpx;
text-align: center;
.score-item-name{
font-size: 28rpx;
line-height: 36rpx;
margin-bottom: 4rpx;
}
.score-item-score{
font-size: 38rpx;
line-height: 46rpx;
font-weight: bold;
}
&.score-item1{
left: 50%;
margin-left: -60rpx;
bottom: 50%;
transform: translateY(v-bind(scoreMarginAbsY));
}
&.score-item2{
left: calc( 50% + v-bind(scoreMarginX));
bottom: calc(v-bind(scoreMarginPercentY) - 30rpx);
}
&.score-item3{
right: calc( 50% + v-bind(scoreMarginX));
bottom: calc(v-bind(scoreMarginPercentY) - 30rpx);
}
}
}
</style>