113 lines
2.5 KiB
Vue
113 lines
2.5 KiB
Vue
<template>
|
|
<div class="go-smart-campus-metrics">
|
|
<div class="title" :style="{ color: option.titleColor, fontSize: option.titleSize + 'px' }">{{ option.title }}</div>
|
|
<div class="metrics-grid">
|
|
<div v-for="(item, index) in option.dataset" :key="index" class="metric-item">
|
|
<div class="metric-background"></div>
|
|
<div class="metric-content">
|
|
<div class="item-label" :style="{ color: option.labelColor, fontSize: option.labelSize + 'px' }">{{ item.label }}</div>
|
|
<div class="item-value">
|
|
<span :style="{ color: option.valueColor, fontSize: option.valueSize + 'px' }">{{ item.value }}</span>
|
|
<span :style="{ color: option.unitColor, fontSize: option.unitSize + 'px' }">{{ item.unit }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { PropType, computed } from 'vue'
|
|
import { option as configOption } from './config'
|
|
|
|
const props = defineProps({
|
|
chartConfig: {
|
|
type: Object as PropType<{ option: typeof configOption }>,
|
|
required: true
|
|
}
|
|
})
|
|
|
|
const option = computed(() => props.chartConfig.option)
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.go-smart-campus-metrics {
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: #0F1C3D;
|
|
padding: 20px;
|
|
box-sizing: border-box;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
|
|
.title {
|
|
font-weight: bold;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.metrics-grid {
|
|
width: 100%;
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
grid-gap: 20px;
|
|
}
|
|
|
|
.metric-item {
|
|
position: relative;
|
|
padding: 20px;
|
|
box-sizing: border-box;
|
|
text-align: center;
|
|
overflow: hidden;
|
|
|
|
.metric-background {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: radial-gradient(circle, v-bind('option.accentColor1') 0%, rgba(15, 28, 61, 0) 70%);
|
|
opacity: 0.3;
|
|
z-index: 1;
|
|
}
|
|
|
|
.metric-content {
|
|
position: relative;
|
|
z-index: 2;
|
|
}
|
|
|
|
.item-label {
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.item-value {
|
|
span:first-child {
|
|
font-weight: bold;
|
|
margin-right: 5px;
|
|
}
|
|
}
|
|
|
|
&::before, &::after {
|
|
content: '';
|
|
position: absolute;
|
|
width: 50px;
|
|
height: 50px;
|
|
border-style: solid;
|
|
border-color: v-bind('option.accentColor2');
|
|
}
|
|
|
|
&::before {
|
|
top: -5px;
|
|
left: -5px;
|
|
border-width: 2px 0 0 2px;
|
|
}
|
|
|
|
&::after {
|
|
bottom: -5px;
|
|
right: -5px;
|
|
border-width: 0 2px 2px 0;
|
|
}
|
|
}
|
|
}
|
|
</style>
|