<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<script type="module" src="./main.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
index.html
global.css
main.js
App.vue
package.json
dataRange.vue
assets
现在支持上传本地图片了!
index.html
global.css
body {
background-color: #fefefe;
}
编辑器加载中
main.js
import { createApp } from 'vue'
import './global.css'
import App from './App.vue'
import ElementPlus from "element-plus";
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')
编辑器加载中
App.vue
<script setup lang='ts'>
import DataRange from './dataRange.vue'
import { ref ,onMounted} from "vue"
const DatarangeOpt = ref({
title: "心率稳定性",
unit: "",
uprange: [{
val: "",
width: "60px",
}, {
val: "27.9",
width: "60px",
}, {
val: "90",
width: "60px",
}, {
val: "110",
width: "60px",
}, {
val: "130",
width: "60px",
}, {
val: "200",
width: "60px",
}],
upval: '0',
downrange: [],
downval: "",
colorRange: [{
width: "60px",
height: "20px",
color: "#f55f44"
}, {
width: "60px",
height: "20px",
color: "#fdbe00"
}, {
width: "60px",
height: "20px",
color: "#55e0b2"
}, {
width: "60px",
height: "20px",
color: "#3ad29f"
}, {
width: "60px",
height: "20px",
color: "#0cda95"
}]
})
const DatarangeOpt1 = ref({
title: "压力指数",
unit: "",
type: "right",
uprange: [{
val: "极差",
width: "60px",
}, {
val: "差",
width: "60px",
}, {
val: "正常",
width: "60px",
}, {
val: "好",
width: "60px",
}, {
val: "优",
width: "60px",
}, {
val: "",
width: "60px",
}],
upval: '',
downrange: [
{
val: "150",
width: "56px",
},
{
val: "130",
width: "56px",
}, {
val: "110",
width: "60px",
}, {
val: "90",
width: "60px",
}, {
val: "70",
width: "60px",
}, {
val: "50",
width: "60px",
},{
val: "50",
width: "0px",
}
],
downval: "180",
colorRange: [{
width: "60px",
height: "35px",
color: "#f55f44"
}, {
width: "60px",
height: "35px",
color: "#fdbe00"
}, {
width: "60px",
height: "35px",
color: "#55e0b2"
}, {
width: "60px",
height: "35px",
color: "#3ad29f"
}, {
width: "60px",
height: "35px",
color: "#0cda95"
}]
})
DatarangeOpt1.value.colorRange.reverse();
DatarangeOpt1.value.uprange.reverse();
</script>
<template>
<div class="container">
<DataRange :option="DatarangeOpt"/>
<br>
<DataRange :option="DatarangeOpt1"/>
</div>
</template>
<style lang="scss" scoped>
$bg: #f0f2f5;
.container {
background: $bg;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.logo {
height: 40px;
width: 40px;
margin-top: 20px;
}
</style>
编辑器加载中
package.json
注意:新添加的依赖包首次加载可能会报错,稍后再次刷新即可
{
"dependencies": {
"vue": "3.5.15",
"element-plus": "^2.8.6"
}
}
编辑器加载中
dataRange.vue
<!-- 数值范围组件 -->
<template>
<div class="container-range">
<el-row>
{{ props.option.title }}
</el-row>
<el-row v-if="props.option.uprange.length > 0" style="display: flex">
<div v-for="(item, index) in props.option.uprange" class="uptitle" :style="{ width: item.width }">
{{ index != props.option.uprange.length - 1 ? item.val : "" }}
</div>
</el-row>
<el-row style="display: flex;position: relative;">
<!-- 用span,防止使用div污染选择器使选择器选不中 -->
<span id="upflag" :style="{ marginLeft: upleft + 'px' }" v-if="props.option.upval!=''">
</span>
<span id="downflag" :style="{ marginLeft: downleft + 'px' }" v-if="props.option.downval!=''">
</span>
<div class="color-item" v-for="(item, index) in props.option.colorRange"
:style="{ backgroundColor: item.color, width: item.width, height: item.height }">
</div>
</el-row>
<el-row v-if="props.option.downrange.length > 0" style="display: flex" >
<div v-for="(item, index) in props.option.downrange" class="downtitle" :style="{ width: item.width }">
{{ index != props.option.downrange.length - 1 ? item.val : "" }}
</div>
</el-row>
</div>
</template>
<script setup lang="ts">
import { ref,onMounted } from 'vue';
const props = defineProps({
option: {
type: Object,
default: () => {
return {
title: "",
unit: "",
uprange: [] as any[],//val, width
upval: "",
downrange: [] as any[],
downval: "",
colorRange: [] as any[], //width ,height,color,
type:"right"
}
}
}
})
const upleft = ref(50);
const downleft = ref(50);
//计算靠左的位置
function getUpLeft() {
let left = 0;
let preval = 0;
let upval = parseFloat(props.option.upval);
for (let i = 1; i < props.option.uprange.length; i++) {
let curval = parseFloat(props.option.uprange[i].val);
preval = parseFloat(props.option.uprange[i - 1].val) || 0;
if (upval < curval) {
left += (upval - preval) * 1.0 / (curval - preval) * parseFloat(props.option.uprange[i].width);
break;
} else {
left += parseFloat(props.option.uprange[i].width);
left += 3;
}
console.log("left:", left);
}
upleft.value = left;
}
function getDownLeft() {
let left = 0;
let preval = 0;
let downval = parseFloat(props.option.downval);
for (let i = 1; i < props.option.downrange.length; i++) {
let curval = parseFloat(props.option.downrange[i].val);
preval = parseFloat(props.option.downrange[i - 1].val) || 0;
if (downval < curval) {
left += (downval - preval) * 1.0 / (curval - preval) * parseFloat(props.option.downrange[i].width);
break;
} else {
left += parseFloat(props.option.downrange[i].width) + 3;
}
}
downleft.value = left;
}
function getDownLeftRever() {
let allwidth = 0;
let len = props.option.colorRange.length;
for (let i = 0; i < len; i++){
allwidth+= parseFloat(props.option.colorRange[i].width);
}
allwidth+=3*Math.max(0,len-1);
let right = 0;
let preval = 0;
console.log(props.option.downrange);
let downval = parseFloat(props.option.downval);
len = props.option.downrange.length-1;
for (let i = len - 1; i >=0; i--) {
let curval = parseFloat(props.option.downrange[i].val);
preval = parseFloat(props.option.downrange[i + 1].val) || 0;
console.log("curval,preval",downval,curval,preval);
if (downval < curval) {
right += (downval - preval) * 1.0 / (curval - preval) * parseFloat(props.option.downrange[i].width);
break;
} else {
right += parseFloat(props.option.downrange[i+1].width) + 3;
}
console.log(right);
}
console.log(allwidth,right);
downleft.value = allwidth - right;
}
function getUpLeftRever() {
let allwidth = 0;
let len = props.option.colorRange.length;
for (let i = 0; i < len; i++){
allwidth+= parseFloat(props.option.colorRange[i].width);
}
allwidth+=3*Math.max(0,len-1);
let right = 0;
let preval = 0;
let upval = parseFloat(props.option.upval);
len = props.option.uprange.length-1;
console.log("upval",upval,props.option.uprange);
for (let i = len - 1 ; i >=0; i--) {
let curval = parseFloat(props.option.uprange[i].val);
console.log("curval,preval",i,curval);
preval = parseFloat(props.option.uprange[i + 1].val) || 0;
console.log("curval,preval",i,curval,preval);
if (upval < curval) {
right += (upval - preval) * 1.0 / (curval - preval) * parseFloat(props.option.uprange[i].width);
break;
} else {
right += parseFloat(props.option.uprange[i].width) + 3;
}
}
console.log(allwidth,right);
upleft.value = allwidth - right;
}
onMounted(()=>{
if(props.option.type=="right"){
console.log("right");
//getUpLeftRever();
getDownLeftRever();
} else {
getUpLeft();
getDownLeft();
}
})
</script>
<style scoped>
#upflag,
#downflag {
position: absolute;
top: -5px;
left: 0;
width: 5px;
height: 30px;
background-image: url("./assets/bz1.png");
background-repeat: no-repeat;
background-size: 100% 100%;
}
#upflag {
top: -10px;
}
#downflag {
top: 0;
}
.downtitle,
.uptitle {
text-align: left;
line-height: 30px;
}
.color-item {
margin-right: 3px;
}
.color-item:first-of-type {
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
}
.color-item:last-of-type {
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
}
</style>
编辑器加载中
预览页面