performance为渐变色带,能大幅提升可视化效果,优雅美观,同时也可以自定义程度,比如60以下就需要警告或者表示危险,就可以用红色渐变绿色,将渐变点设置在60%的位置,这样渐变色带在美观的同时本身也能带有更多的信息。
这里performance为多色色带,只要选好配色,就能明亮简洁,信息全面,同时也能做维度筛选。直观来看是综合的色带,但是每个具体的维度都能展示,并且可以隐藏部分维度重新排序(也就能实现单维度展示和排序)
这里的核心思想是通过background,相当于将色带当做背景图片添加到表格中,所以色带中也可以添加合适的文字说明,比如具体的数值或者简洁描述等。
先上html代码:
<el-table :data="rankingDataFormatted" stripe>
<el-table-column prop="ranking" label="Rank" width="100"></el-table-column>
<el-table-column prop="cityName" label="Country" width="200"></el-table-column>
<el-table-column prop="score" label="Score" width="200"></el-table-column>
<el-table-column label="Performance">
<template v-slot="scope">
<!-- 动态绑定样式,通过getBackgroundColor获得色带 -->
<div :style="{background: getBackgroundColor(scope.row.score), height: '20px'}"></div>
</template>
</el-table-column>
</el-table>
就是一个elementui-plus的table,用了一个插槽用来放置色带背景。
再上js代码:
const getBackgroundColor = (score) =>{
const percentage = score / 100;
const filledPercentage = Math.min(percentage, 1);
const filledColorHead = '#95CCDE';
const filledColorFoot = '#A9B2D4';
const emptyColor = '#EEEEEE';
return `linear-gradient(to right, ${filledColorFoot}, ${filledColorHead} ${filledPercentage * 100}%, ${emptyColor} ${filledPercentage * 100}%)`;
}
这里要注意的是:
大致思路跟渐变色带一样,都是用动态样式,但是这里细节多一些,我尽可能放整段代码便于理解和阅读。
<el-select
v-model="selectedDimension"
multiple
placeholder="Select"
style="width: 190px"
>
<el-option
v-for="item in dimensionColors"
:key="item.value"
:label="item.label"
:value="item.value"
>
<div class="flex items-center">
<el-tag :color="item.value" style="margin-right: 8px" size="small" />
<span :style="{ color: item.value }">{{ item.label }}</span>
</div>
</el-option>
<template #tag>
<el-tag
v-for="color in selectedDimension"
:key="color.value"
:color="color"
/>
</template>
</el-select>
<el-card class="container">
<el-table :data="rankingDetailData" stripe>
<el-table-column type="index" label="Rank" width="100"></el-table-column>
<el-table-column
prop="cityName"
label="Country"
width="200"
></el-table-column>
<el-table-column label="Score" width="200" sortable="custom">
<template v-slot="scope">
<!-- 实现可变数据的动态排序 -->
{{ formatScore(scope.row) }}
</template>
</el-table-column>
<el-table-column label="Performance">
<template v-slot="scope">
<div
:style="{
background: getBackgroundColor(scope.row),
height: '20px',
}"
></div>
</template>
</el-table-column>
</el-table>
</el-card>
其中:
再上js代码:
// 各维度颜色
const dimensionColors = ref([
{
value: "#FF6600",
label: "创新发展",
},
{
value: "#FFDE0A",
label: "协调发展",
},
{
value: "#1EC79D",
label: "绿色发展",
},
{
value: "#14CCCC",
label: "开放发展",
},
{
value: "#4167F0",
label: "共享发展",
},
]);
// 选中的维度
const selectedDimension = ref([]);
// 将所有维度颜色添加到初始框中
dimensionColors.value.forEach((color) => {
selectedDimension.value.push(color.value);
});
// 搞定多维度的色带
const getBackgroundColor = (row) => {
// 先定下来颜色
const innovationColor = "#FF6600";
const operateColor = "#FFDE0A";
const greenColor = "#1EC79D";
const openColor = "#14CCCC";
const sharingColor = "#4167F0";
const emptyColor = "#EEEEEE";
var arr = [];
// 将选中的颜色放到arr中,arr用来确定选择框里面放什么颜色
selectedDimension.value.forEach((element) => {
dimensionColors.value.forEach((item) => {
if (item.value == element) {
var data = {};
data.dimension = item.label;
data.score = Number(row[item.label]);
arr.push(data);
return;
}
});
});
// 产出色带,百分号里面的数据可以减去0.3,能添加柔和效果
return `linear-gradient(to right,
${innovationColor} 0%, ${innovationColor} ${arraySum(arr, 1)}%,
${operateColor} ${arraySum(arr, 1)}%, ${operateColor} ${arraySum(arr, 2)}%,
${greenColor} ${arraySum(arr, 2)}%, ${greenColor} ${arraySum(arr, 3)}%,
${openColor} ${arraySum(arr, 3)}%, ${openColor} ${arraySum(arr, 4)}%,
${sharingColor} ${arraySum(arr, 4)}%, ${sharingColor} ${arraySum(arr, 5)}%,
${emptyColor} ${arraySum(arr, 5)}%, ${emptyColor} 100%)`;
};
// 数组求和方法,适用于getBackgroundColor方法
const arraySum = (arr, n) => {
let sum = 0;
var dimensionOrder = [
"创新发展",
"协调发展",
"绿色发展",
"开放发展",
"共享发展",
];
for (let i = 0; i < n; i++) {
arr.forEach((item) => {
if (item.dimension == dimensionOrder[i]) {
sum += item.score;
}
});
}
return sum;
};
最巧妙的地方在于,select选择框里面的颜色是无序的,经过反复的去掉选择和重复选择,颜色的排列是杂乱的,但是色带的颜色始终是有序的。这样的好处在于,规定的色带只会出现在特定的位置,如果某个色带被取消勾选,那么它所代表的色带的长度就是零。其后面的色带会依次前移,重新勾选之后这个色带也会出现在原先的位置,而不是出现在色带最后,这样可以实现“颜色-->维度”和“位置-->维度”两方面的一一对应,大大提升了可视化体验,阻止了重复操作中信息的熵增。
写代码不能局限于使用他人或机构、组织封装的代码,而需要更多的去了解人家的底层设计,多尝试二次开发,比如这里的后端排序接口,只需要一点点思路上的变动就能变成前端的动态排序接口,这就是思路带来的改变,如果只会用官方文档提供的API,是做不来一个优质的程序员的。
更多丰富的前端内容请看:各种前端问题的技巧和解决方案
更多elementui小技巧:vue2/3+elementui,满足实际开发需求的各种“骚操作”
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~