JS前端模擬Excel條件格式實(shí)現(xiàn)數(shù)據(jù)條效果
需求背景
最近業(yè)務(wù)中遇到一個(gè)有意思的需求,是要在現(xiàn)有的表格中實(shí)現(xiàn)類似 Excel 中的數(shù)據(jù)條的效果,在數(shù)據(jù)比較多的時(shí)候單純看表格里的數(shù)字會(huì)比較密集且不容易對比,加上數(shù)據(jù)條之后就比較明顯的看出數(shù)據(jù)的對比情況,也讓表格看起來生動(dòng)了一些,這算是融合了表格和柱狀圖的優(yōu)點(diǎn)。
先來看下 Excel 的效果

下面記錄下實(shí)現(xiàn)過程和原理。
需求分析
通過圖片可以看出共有幾種情況:
- 只有正值:數(shù)據(jù)條全部向右
- 只有負(fù)值:數(shù)據(jù)條全部向左
- 正負(fù)值都有:正負(fù)值會(huì)以一個(gè)軸線做分割分布在左右兩側(cè),根據(jù)正負(fù)值的多少軸線的位置也會(huì)相應(yīng)的偏左或偏右
實(shí)現(xiàn)邏輯
實(shí)現(xiàn)這個(gè)效果的前提,我們要知道每列數(shù)據(jù)的最大值max和最小值min,最大值的數(shù)據(jù)條寬度就是100%,下面先用偽代碼梳理下邏輯。
全是正值和全是負(fù)值的情況,這種情況就比較簡單了,就是計(jì)算單元格的值占最大值的比例,計(jì)算公式是這樣:數(shù)據(jù)條寬度 = (當(dāng)前值 / max) * 100
正負(fù)值都有的情況多了一個(gè)“軸線位置“的計(jì)算和”數(shù)據(jù)條偏移量“計(jì)算
軸線位置 = (Math.abs(min) / (max - min)) * 100
數(shù)據(jù)條寬度 = (Math.abs(當(dāng)前值) / (max - min)) * 100
// 當(dāng)前值 < 0 時(shí)數(shù)據(jù)條在軸線左邊,改變 right 值 // 數(shù)據(jù)條的總長為100% right = 100 - 軸線位置 // 當(dāng)前值 > 0 時(shí)數(shù)據(jù)條在軸線右邊,改變 left 值 left = 軸線位置
軸線位置邏輯其實(shí)是 "最小值到0的距離在總長度(max-min)之間的占比",我們知道數(shù)字與0之間的距離其實(shí)就是絕對值的計(jì)算,那么轉(zhuǎn)換為公式來表示就是:
數(shù)據(jù)條的寬度就是 “當(dāng)前值到0的距離在總長度(max-min)之間的占比”,公式表示:
- 數(shù)據(jù)條的偏移量,這里需要知道是向左還是向右偏移(最終是通過改變元素CSS的 left、right 屬性來實(shí)現(xiàn)偏移)
完整代碼實(shí)現(xiàn)
代碼使用 Vue + ElementUI
template 部分
<template>
<el-table :data="tableData" border style="width: 100%">
<el-table-column
v-for="item in columns"
sortable
:key="item.prop"
:prop="item.prop"
:label="item.label"
>
<template slot-scope="scope">
<!-- 數(shù)據(jù)條 -->
<div class="data-bar" :style="renderDataBar(item, scope.row)"></div>
<!-- 軸線 -->
<div class="data-bar-axis" :style="renderAxis(item, scope.row)"></div>
<!-- 當(dāng)前值 -->
<span class="cell-value">{{ scope.row[item.prop] }}</span>
</template>
</el-table-column>
</el-table>
</template>
style 部分
先放 style 部分是為了讓大家對基礎(chǔ)樣式有個(gè)感受,渲染函數(shù)中主要就是動(dòng)態(tài)修改元素的 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: '負(fù)值',
min: -1,
max: -12
},
{
prop: 'mixed',
label: '正負(fù)值',
min: -6,
max: 5
}
],
tableData: []
}
},
created() {
this.initData()
},
methods: {
initData() {
// mock數(shù)據(jù)過程,忽略 ...
this.tableData.push({...})
},
renderDataBar(column, row) {
const { min, max, prop } = column
// 當(dāng)前單元格值
const cellVal = row[prop]
if (cellVal === 0) return { display: 'none' };
let style = {
width: '0',
background: '#409eff'
}
// 全是正值 或 全是負(fù)值
if (min >= 0 || max <= 0) {
const width = ((cellVal / max) * 100).toFixed(2);
style.width = `${width}%`
style = min >= 0 ? { ...style, left: '0' } : { ...style, right: '0' }
}
// 正負(fù)值都有
if (min < 0 && max > 0) {
const range = max - min;
// 軸線位置
const leftOffset = Math.abs((min / range) * 100)
// 數(shù)據(jù)條寬度
const width = ((Math.abs(cellVal / range) * 100)).toFixed(2)
style = cellVal > 0 ? {
width: `${width}%`,
left: `${leftOffset.toFixed(2)}%`
} : {
width: `${width}%`,
background: '#F56C6C', // 負(fù)值進(jìn)行顏色區(qū)分
right: `${(100 - leftOffset).toFixed(2)}%`
}
}
return style;
},
renderAxis(column) {
const { min, max } = column
if (min < 0 && max > 0) {
// 正負(fù)值都有的情況下,顯示軸線
const range = max - min;
const leftOffset = (((0 - min) / range) * 100).toFixed(2)
return {
left: `${leftOffset}%`
}
} else {
return {
display: 'none'
}
}
}
}
}
</script>
最終實(shí)現(xiàn)效果

以上就是JS前端模擬Excel條件格式實(shí)現(xiàn)數(shù)據(jù)條效果的詳細(xì)內(nèi)容,更多關(guān)于JS模擬Excel數(shù)據(jù)條的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
前端通過JavaScript創(chuàng)建修改CAD圖形詳情
這篇文章介紹JavaScript創(chuàng)建修改CAD圖形,創(chuàng)建修改CAD圖形,一般是基于AutoCAD進(jìn)行二次開發(fā),ObjectARX是AutoDesk公司針對AutoCAD平臺上的二次開發(fā)而推出的一個(gè)開發(fā)軟件包,它提供了以C++為基礎(chǔ)的面向?qū)ο蟮拈_發(fā)環(huán)境及應(yīng)用程序接口,能真正快速的訪問AutoCAD圖形數(shù)據(jù)庫2021-10-10
微信小程序 常見問題總結(jié)(4058,40013)及解決辦法
這篇文章主要介紹了微信小程序 常見問題總結(jié)及解決辦法的相關(guān)資料,這里首先對微信小程序的結(jié)構(gòu)進(jìn)行了介紹,然后對常見問題進(jìn)行說明講解,需要的朋友可以參考下2017-01-01
JS輕量級函數(shù)式編程實(shí)現(xiàn)XDM三
這篇文章主要為大家介紹了JS輕量級函數(shù)式編程實(shí)現(xiàn)XDM示例詳解第3/3篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
JavaScript節(jié)點(diǎn)的增刪改查深入學(xué)習(xí)
這篇文章主要為大家介紹了JavaScript節(jié)點(diǎn)的增刪改查深入學(xué)習(xí)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01

