文章详情

需求背景

最近业务中遇到一个有意思的需求,是要在现有的表格中实现类似 Excel 中的数据条的效果,在数据比较多的时候单纯看表格里的数字会比较密集且不容易对比,加上数据条之后就比较明显的看出数据的对比情况,也让表格看起来生动了一些,这算是融合了表格和柱状图的优点。

先来看下 Excel 的效果

JS前端模拟Excel条件格式实现数据条效果

下面记录下实现过程和原理。

需求分析

通过图片可以看出共有几种情况:

只有正值:数据条全部向右

只有负值:数据条全部向左

正负值都有:正负值会以一个轴线做分割分布在左右两侧,根据正负值的多少轴线的位置也会相应的偏左或偏右

实现逻辑

实现这个效果的前提,我们要知道每列数据的最大值max和最小值min,最大值的数据条宽度就是100%,下面先用伪代码梳理下逻辑。

全是正值和全是负值的情况,这种情况就比较简单了,就是计算单元格的值占最大值的比例,计算公式是这样:数据条宽度 = (当前值 / max) * 100

正负值都有的情况多了一个“轴线位置“的计算和”数据条偏移量“计算

轴线位置 = (Math.abs(min) / (max - min)) * 100
数据条宽度 = (Math.abs(当前值) / (max - min)) * 100
// 当前值 < 0 时数据条在轴线左边,改变 right 值
// 数据条的总长为100%
right = 100 - 轴线位置
// 当前值 > 0 时数据条在轴线右边,改变 left 值
left = 轴线位置

轴线位置逻辑其实是 “最小值到0的距离在总长度(max-min)之间的占比”,我们知道数字与0之间的距离其实就是绝对值的计算,那么转换为公式来表示就是:

数据条的宽度就是 “当前值到0的距离在总长度(max-min)之间的占比”,公式表示:

数据条的偏移量,这里需要知道是向左还是向右偏移(最终是通过改变元素CSS的 left、right 属性来实现偏移)

完整代码实现

代码使用 Vue + ElementUI

template 部分

<template>
<el-table :data="tableData" border>
<el-table-column
v-for="item in columns"
sortable
:key="item.prop"
:prop="item.prop"
:label="item.label"
>
<template slot-scope="scope">
<!-- 数据条 -->
<div class="data-bar" :style="renderDataBar(item, scope.row)"></div>
<!-- 轴线 -->
<div class="data-bar-axis" :style="renderAxis(item, scope.row)"></div>
<!-- 当前值 -->
<span class="cell-value">{{ scope.row[item.prop] }}</span>
</template>
</el-table-column>
</el-table>
</template>

style 部分

先放 style 部分是为了让大家对基础样式有个感受,渲染函数中主要就是动态修改元素的 width、left、right 的值

<style>
.el-table .cell-value {
position: relative;
}
.data-bar {
position: absolute;
top: 0;
bottom: 0;
margin: 5px auto;
transition: width 0.2s;
}
.data-bar-axis {
position: absolute;
top: -1px;
bottom: 0;
border-right: 1px dashed #303133;
}
</style>

script 部分

<script>
export default {
data() {
return {
columns: [
{
prop: 'positive',
label: '正值',
min: 1,
max: 10
},
{
prop: 'negative',
label: '负值',
min: -1,
max: -12
},
{
prop: 'mixed',
label: '正负值',
min: -6,
max: 5
}
],
tableData: []
}
},
created() {
this.initData()
},
methods: {
initData() {
// mock数据过程,忽略 ...
this.tableData.push({...})
},
renderDataBar(column, row) {
const { min, max, prop } = column
// 当前单元格值
const cellVal = row[prop]
if (cellVal === 0) return { display: 'none' };
let style = {
width: '0',
background: '#409eff'
}
// 全是正值 或 全是负值
if (min >= 0 || max <= 0) {
const width = ((cellVal / max) * 100).toFixed(2);
style.width = `${width}%`
style = min >= 0 ? { ...style, left: '0' } : { ...style, right: '0' }
}
// 正负值都有
if (min < 0 && max > 0) {
const range = max - min;
// 轴线位置
const leftOffset = Math.abs((min / range) * 100)
// 数据条宽度
const width = ((Math.abs(cellVal / range) * 100)).toFixed(2)
style = cellVal > 0 ? {
width: `${width}%`,
left: `${leftOffset.toFixed(2)}%`
} : {
width: `${width}%`,
background: '#F56C6C', // 负值进行颜色区分
right: `${(100 - leftOffset).toFixed(2)}%`
}
}
return style;
},
renderAxis(column) {
const { min, max } = column
if (min < 0 && max > 0) {
// 正负值都有的情况下,显示轴线
const range = max - min;
const leftOffset = (((0 - min) / range) * 100).toFixed(2)
return {
left: `${leftOffset}%`
}
} else {
return {
display: 'none'
}
}
}
}
}
</script>

最终实现效果

JS前端模拟Excel条件格式实现数据条效果

您可能感兴趣的文章:

  • js 实现汉字简体和繁体之间的互相转换
  • java比较两个json文件的差异及说明
  • jquery.qrcode.js生成二维码并转成图片格式
  • js实现签到日历
  • vue.config.js 的完整配置(超详细)
  • 使用JS实现鼠标放上图片进行放大离开实现缩小功能
  • JavaScript前后端JSON使用方法教程
  • vue的webcamjs集成方式

版权:版权申明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 70068002@qq.com 举报,一经查实,本站将立刻删除。

转载请注明出处:https://www.stntk.com/2559.html

下一篇:

已经没有下一篇了!

相关推荐
JS前端模拟Excel条件格式实现数据条效果
需求背景 最近业务中遇到一个有意思的需求,是要在现有的表格中实现类似 Excel 中的数据条的效果,在数据比较多的时候单纯看表格里的数字会比…
头像
前端开发 2024-05-26
934
js 实现汉字简体和繁体之间的互相转换
简体字 简体字(Simplified Chinese,简体中文),是中国大陆地区目前在用的字体,由官方公布的简体字,主要由传承字以及1950…
头像
前端开发 2024-05-26
713
如何使用nginx配置代理多个前端资源?
背景 两套不同的前端使用同一个后端服务,前端使用的Nginx代理的dist包 前端 vue+elementui 后端 Python+flas…
头像
前端开发 2024-05-26
582
jquery实现ul列表中点击li选择radio
如何利用jquery实现ul列表中点击li选择radio呢? 1、HTML代码 <ul class="list-group"> …
头像
前端开发 2024-05-26
1,133
vue3.2+ts实现在方法中可调用的拟态框弹窗(类el-MessageBox)
公司UI设计的拟态框弹窗跟Element Plus UI的布局不太一致。导致不能够直接修改样式得到想到样式。直接上图。 这个需求最主要的是要…
头像
前端开发 2024-05-26
1,139
前端如何实现网页变灰功能?
今天来从前端的角度看看网页置灰是如何实现的,以及相关使用技巧! 实现思路 先来看看一些主流网站是如何实现置灰的: BiliBili: 京东 …
头像
前端开发 2024-05-26
861
发表评论
暂无评论

还没有评论呢,快来抢沙发~

点击联系客服

在线时间:8:00-16:00

客服电话

400-888-8888

客服邮箱

70068002@qq.com

扫描二维码

关注微信公众号