|
一、 核心需求分析
在做报表开发时,业务部门常希望实现类似 Excel 的三色刻度(Color Scales)功能:根据单元格数值的大小,自动在“红-黄-绿”之间进行颜色渐变。
虽然帆软内置的“条件属性”可以设置背景,但通常只能实现阶梯式变色(如 >90 绿,<60 红),无法实现平滑的线性过渡。为了追求极致的视觉体验,我们利用 JavaScript 结合帆软的 DOM 特性,完美还原了 Excel 的中位数色阶算法。
二、 技术原理
该方案的核心在于分段线性插值算法:
* 区间定位:将数据分为 [最小值, 中位数] 和 [中位数, 最大值] 两个逻辑区间。
* 动态采样:自动获取当前列或指定区域的极值,确保色阶随数据刷新自动调整。
* RGB 插值:根据数值在区间内的百分比位置,计算出对应的 R、G、B 通道值,实现色彩的无缝平滑。
* 视觉优化:引入亮度感知算法,当背景颜色过深时,自动切换文字颜色(黑/白),保证易读性。
三、 核心代码实现
本方案采用通用函数封装,支持扩展单元格和固定区域两种模式。只需在“模板 > 模板 Web 属性 > 分页预览设置 > 加载结束事件”中添加即可。
注:要添加功能的单元格需要设置自定义内容提示,在“单元格属性 > 其他 > 内容提示 > 自定义”输入'=$$$'即可
/**
* 帆软报表 Excel 级动态色阶插件逻辑
* 适用场景:动态扩展列、固定单元格区域
*/
function applyExcelColorScale(target, colors, mode) {
// 1. 定位单元格 (支持扩展单元格名称或固定数组)
var selector = (mode === 'expansion')
? "td[cef='" + target + "']"
: target.map(function(n) { return "td[cef='" + n + "']"; }).join(",");
var $cells = $(selector);
var values = [];
// 2. 原始数据采集 (从 title 属性规避格式化干扰)
$cells.each(function() {
var val = parseFloat($(this).attr("title"));
if (!isNaN(val)) values.push(val);
});
if (values.length < 2) return;
// 3. 计算 Excel 50百分位 (中位数) 逻辑
values.sort(function(a, b) { return a - b; });
var min = values[0], max = values[values.length - 1];
var lowMid = Math.floor((values.length - 1) / 2);
var highMid = Math.ceil((values.length - 1) / 2);
var mid = (values[lowMid] + values[highMid]) / 2;
// 4. 颜色渲染
$cells.each(function() {
var val = parseFloat($(this).attr("title"));
if (isNaN(val)) return;
var r, g, b, p, start, end;
if (val <= mid) {
p = (mid === min) ? 1 : (val - min) / (mid - min);
start = colors.min; end = colors.mid;
} else {
p = (max === mid) ? 1 : (val - mid) / (max - mid);
start = colors.mid; end = colors.max;
}
r = Math.floor(start.r + (end.r - start.r) * p);
g = Math.floor(start.g + (end.g - start.g) * p);
b = Math.floor(start.b + (end.b - start.b) * p);
// 文字颜色自适应算法
var brightness = (r * 299 + g * 587 + b * 114) / 1000;
$(this).css({
"background-color": "rgb(" + r + "," + g + "," + b + ")",
"background-image": "none",
"color": brightness < 110 ? "#FFFFFF" : "#000000"
});
});
}
// 调用示例
setTimeout(function() {
var config = {
min: { r: 248, g: 105, b: 107 }, // 红
mid: { r: 255, g: 235, b: 132 }, // 黄
max: { r: 99, g: 190, b: 123 } // 绿
};
// 模式 A: G13 扩展出的整列
applyExcelColorScale("G13", config, 'expansion');
// 模式 B: 指定的固定区域 S2:S8
applyExcelColorScale(["S2","S3","S4","S5","S6","S7","S8"], config, 'fixed');
}, 300);
四、 方案优势
* 对标 Excel:采用中位数逻辑,有效解决了长尾数据(极值干扰)导致的颜色分配不均问题。
* 抗干扰力强:直接读取单元格 title 原始值,不受千分位、单位、公式格式化的影响。
* 自适应排版:内置背景亮度检测,即便背景是深红色,文字也能清晰可见。
* 复用性强:一次封装,多列调用,不同列可配置不同的配色方案(如:红-黄-绿 或 白-蓝-深蓝)。 |