JS模拟实现Excel条件格式中的色阶效果
作者:旋涡
这篇文章主要为大家详细介绍了如何利用JavaScript模拟实现Excel条件格式中的色阶效果,文中的示例代码讲解详细,感兴趣的小伙伴可以尝试一下
本篇文章是模拟Excel条件格式第二篇“色阶”的实现原理,上篇《前端模拟 Excel 条件格式—数据条效果实现》
需求背景
公司做的数据分析系统中想要将Excel中的条件格式功能搬过来。原因:纯表格中的数据展示只有字符没有样式,比较难发现更多维度的信息,当有了色阶效果后分析人员可以更容易在数据中发现更多信息如:是否波动剧烈、是否呈聚合趋势、是否有规律等。
先看Excel的标准效果:
下面我们试着分析如何实现这样的效果。
需求分析
按列展示、要根据单元格的值自动计算出对应的色阶值,将对应的颜色填充到单元格中。 按此分析可以肯定的是这不是一个简单的CSS渐变可以实现的,这里会涉及到对色值之间的色阶计算、单元格需要进行计算来动态生成样式。
实现逻辑
与上一篇数据条的实现有个相同的前提,我们要知道每列数据的最大值max和最小值min,以及计算当前值在最大最小值中的位置。
先来实现一个获取色阶颜色值的方法,关于色阶的计算使用到的是线性插值的方式,有一个标准的公式,下面是 ChatGPT 回答:
实现代码: 用到了一个颜色转换库:Color
getColor(value, min, max, colors) { if (value < min) return colors[0] if (value > max) return colors[colors.length - 1] // 将 hex 颜色值转换为 rgb 格式 colors = colors.map(c => Color(c).object()) const colorsLen = colors.length; // 计算当前值在最大最小值中的位置 const rang = max - min; let weight = (value - min) / rang; // 计算颜色列表的最后一个索引值 const endIndex = Math.max(Math.ceil((colorsLen - 1) * weight), 1); // 获取两个颜色最小颜色(起始色)、最大颜色(结束色) const minColor = colors[endIndex - 1] const maxColor = colors[endIndex] // 计算色阶比例 weight = weight * (colorsLen - 1) - (endIndex - 1) // 线性插值公式 const r = (1 - weight) * minColor.r + weight * maxColor.r const g = (1 - weight) * minColor.g + weight * maxColor.g const b = (1 - weight) * minColor.b + weight * maxColor.b return `rgb(${r},${g},${b})` }
完整代码
代码使用 Vue + ElementUI
template 部分
<template> <el-table :data="tableData" border stripe style="width: 80%" :cell-style="cellStyle" > <el-table-column v-for="item in columns" sortable :key="item.prop" :prop="item.prop" :label="item.label" > <template slot-scope="scope"> <span class="cell-value">{{ scope.row[item.prop] }}</span> </template> </el-table-column> </el-table> </template>
script 部分
import Color from 'color'; import { tableColumns, tableData } from './mock-data.js'; export default { name: 'color-scale', data() { return { // 数据mock部分放在下方 columns: tableColumns, tableData: tableData(), // 红黄绿 colors: ['#f8696b', '#ffeb84', '#63be7b'], // 绿黄红 colors2: ['#63be7b', '#ffeb84', '#f8696b'] } }, methods: { getColor(value, min, max, colors) { // 同上... }, cellStyle({ row, column }) { const { property } = column; if (property !== 'car') { const obj = this.columns.find(item => item.prop === property); const min = obj.min; const max = obj.max; const cellVal = row[property] const colors = property === 'order' ? this.colors2 : this.colors return { background: this.getColor(cellVal, min, max, colors) } } return {} } } }
mock 数据
不重要,感兴趣可以参考
// mock-data.js export const tableColumns = [ { prop: 'car', label: '车型', min: 1, max: 20 }, { prop: 'order', label: '订单量', min: 10, max: 30 }, { prop: 'sale', label: '销售额', min: 100, max: 120 }, { prop: 'aggregate', label: '呈聚合状', min: 10, max: 104 }, { prop: 'uneven', label: '随机数据', min: 50, max: 5000 } ]; export const tableData = function () { const aggregateNums = [10, 20, 30, 40, 50, 60, 70, 80, 81, 82, 83, 84, 85, 86, 87, 100, 101, 102, 103, 104]; return Array.from({ length: 20 }, (_, index) => ({ car: `车型${index + 1}`, order: index + 10, sale: index + 100, aggregate: aggregateNums[index], uneven: getRandomIntInclusive(50, 5000) // 随机 })) } export const getRandomIntInclusive = (min, max) => { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1)) + min; }
最终效果
总结
- 实现此功能中最重要也是最难的点就是在于色阶值的计算、线性插值公式的理解,这一步理解透了其他的就简单了。
- 善用 ChatGPT 手动捂脸
以上就是JS模拟实现Excel条件格式中的色阶效果的详细内容,更多关于JS模拟Excel色阶的资料请关注脚本之家其它相关文章!