Toggle navigation
仪表盘模拟角度渐变
By
深***子
2020-09-01 01:23:29
脚本
16
21
作品使用的第三方脚本
数据管理
上传数据
支持小于 5M 任意格式(csv, xlsx, json, xml, ...)的数据文件
上传后可以通过生成的文件链接异步获取托管的数据。
历史数据
0 条
无历史数据
代码修改记录
信息提示
保存作品
对当前截图不满意?你还可以
上传本地截图
重新截图
作品名称
作品描述
标签
geo
grid
legend
markLine
markPoint
bar
effectScatter
line
lines
map
timeline
title
toolbox
tooltip
visualMap
作品默认版本
最新
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
20:11:45
图表已生成
整理代码
刷新
代码
/* * 角度(圆锥)渐变 * 原理: 使用axisLine的color来模拟实现, 平滑的渐变过渡借助axisTick实现. * 其他方案: axisTick的color设为image, 用角度渐变图片填充. 1.当使用ps生成的png图片时,此方案的问题是需要保持echarts大小不变, 尺寸一旦变化就需要修改图片的分辨率, 和裁剪图片,适应场景有限制 * 2. 为了解除ps的限制,可以使用canvas的create-conical-gradient polyfill 根据echarts尺寸以及仪表盘radius动态生成角度渐变的图片填充在axisTick中 * * 不均匀刻度 * 原理:通过计算每个splitNumber的单位刻度值实现,公式在81行parseValue方法 */ // 角度渐变的关键色值,在ps中获取 // 一定要注意ps中角度渐变的起始角度要保持和图形的起始角度(startAngle)一致 const colors = [ [0, 235, 15, 15], [0.1, 235, 15, 15], [0.16, 255, 246, 0], [0.4, 15, 235, 103], [0.54, 15, 235, 103], [0.67, 255, 246, 0], [0.78, 235, 15, 15], [0.9, 0, 99, 177], [1, 235, 15, 15], ]; // 将如: 0.04-0.16之间的渐变值补全 const gradientColors = []; colors.forEach((color, i) => { if (i === colors.length - 1) return; let maxDiffValue = 0; const diffs = color.map((s, j) => { const diff = s - colors[i + 1][j]; const positiveDiff = Math.abs(diff); if (Math.abs(maxDiffValue) < positiveDiff) { maxDiffValue = positiveDiff; } return diff; }); gradientColors.push([color[0], `rgb(${color.slice(1).join(',')})`]); let start = color[0]; const end = colors[i + 1][0]; const step = (end - start) / maxDiffValue; for (let k = 0; k < maxDiffValue - 1; k++) { let rgb = 'rgb($0,$1,$2)'; for (let o = 1; o < color.length; o++) { let c = color[o]; c = c - diffs[o] / maxDiffValue; color[o] = c; rgb = rgb.replace(`$${o - 1}`, c); } start = start + step; gradientColors.push([start, rgb]); } }); const lastColor = colors[colors.length - 1]; gradientColors.push([lastColor[0], `rgb(${lastColor.slice(1).join(',')})`]); // 测试数据 const testData = { startAngle: 225, endAngle: -45, splitNumber: 6, max: 65, data: [30], }; // 仪表盘axisLabel展示的值,个数为splitNumber + 1 const axisLabelData = [0, 40, 45, 50, 55, 60, 65]; // 仪表盘axisLabel根据splitNumber生成的值 const axisLabelOriginData = (() => { const data = []; for (let index = 0; index < testData.splitNumber + 1; index++) { // echarts自动计算axisLabel时, 精确的是10位小数 data.push(+((testData.max / testData.splitNumber) * index).toFixed(10)); } return data; })(); // 将正常值转为指针偏转的值 function parseValue(x, [kp, kn], [zp, zn]) { if (x === 0) return 0; const y = ((zn - zp) / (kn - kp)) * (x - kp) + zp; return y; } let value = testData.data[0]; let valueIndex = -1; axisLabelData.some((item, index) => { valueIndex = index; return value <= item; }); const k = [axisLabelData[valueIndex - 1], axisLabelData[valueIndex]]; const z = [axisLabelOriginData[valueIndex - 1], axisLabelOriginData[valueIndex]]; value = parseValue(value, k, z); // 外层渐变圆环 const baseOut = { type: 'gauge', axisLabel: { show: false, }, axisLine: { show: false, lineStyle: { color: gradientColors, // 因为使用axisLine填充的颜色之间会存在透明间隔, 所以使用axisTick来实现渐变平滑过渡. }, }, axisTick: { length: 4, lineStyle: { color: 'auto', width: 2, // 调整width和splitNumber来使渐变平滑过渡 }, splitNumber: 150, // 调整width和splitNumber来使渐变平滑过渡 }, splitLine: { show: false, lineStyle: { color: 'auto', }, }, detail: { show: false, }, }; // 内层刻度和指针 const baseInner = { radius: '70%', type: 'gauge', axisLine: { show: false, lineStyle: { color: gradientColors, }, }, splitLine: { length: 12, lineStyle: { color: 'auto', }, }, axisTick: { lineStyle: { width: 2, color: 'auto', }, splitNumber: 10, }, pointer: { width: 5, length: '70%', }, axisLabel: { formatter(value) { const index = axisLabelOriginData.findIndex((item) => item === value); return axisLabelData[index]; }, }, }; option = { series: [ baseOut, { ...baseInner, ...testData, data: [value], detail: { // 只支持字符串和函数 formatter: String(testData.data[0]), }, }, ], };