uchart升级到2.0后,加入了很多渐变,但是所有渐变都是基于线性渐变和径向渐变的,对于弧线进度条而言,这种渐变显得不是那么合理。
当颜色从#f04864(红色) 渐变 到 #2fc25b(绿色)时
现有的渐变效果如下(从左到右的线性渐变):
扩展的 弧线渐变 效果如下:
扩展的 进度多颜色渐变 效果如下:
如果进度颜色由2种颜色,增加为3种颜色 '#f04864','#ffaa00','#2fc25b' ,效果如下:
如果进度颜色由3种颜色,增加为4种颜色 '#f04864','#ffaa00','#1890ff','#2fc25b' ,效果如下:
其中进度颜色数组可以支持无限添加
代码中需要做如下修改:
1、增加部分处理函数
function clearArc(opts, context, x,y,radius){
//context清除圆形区域。圆心(x,y),半径radius
var calcWidth=radius-opts.stepClear;
var calcHeight=Math.sqrt(radius*radius-calcWidth*calcWidth);
var posX=x-calcWidth;
var posY=y-calcHeight;
var widthX=2*calcWidth;
var heightY=2*calcHeight;
if(opts.stepClear<=radius){
context.clearRect(posX,posY,widthX,heightY);
opts.stepClear+=1;
clearArc(opts, context, x,y,radius);
}
}
function getMixColor(color1, color2, blv){
//获取2种颜色按blv混合后的颜色,blv必须介于0与1,blv接近0则颜色接近color1, blv接近1则颜色接近color2
var start = color1.length === 4 ? color1.substr(1).split('').map(function (s) { return 0x11 * parseInt(s, 16); }) : [color1.substr(1, 2), color1.substr(3, 2), color1.substr(5, 2)].map(function (s) { return parseInt(s, 16); })
var end = color2.length === 4 ? color2.substr(1).split('').map(function (s) { return 0x11 * parseInt(s, 16); }) : [color2.substr(1, 2), color2.substr(3, 2), color2.substr(5, 2)].map(function (s) { return parseInt(s, 16); })
var zs = Math.abs(parseInt(blv) % 2);
var ms = Math.abs(zs - Math.abs(blv == 1 ? 1 : blv % 1));
ms = ms < 0 ? 1 + ms : ms;
var me = 1 - ms, so = [];
for (var j = 0; j < 3; j++){
so[j] = Math.round((start[j] * me + end[j] * ms)).toString(16);
so[j] = (so[j].length === 1) ? '0' + so[j] : so[j];
}
return '#' + so.join('');
}
function drawArcbarLinear(opts, config, context, x, y, radius, rs,re, borderW, color1, color2){
//弧形渐变
re = rs > re ? re+2 : re;
rs -= 0.5;
re -= 0.5;
rs *= Math.PI;
re *= Math.PI;
var ms, me, so = [], color;
var start = color1.length === 4 ? color1.substr(1).split('').map(function (s) { return 0x11 * parseInt(s, 16); }) : [color1.substr(1, 2), color1.substr(3, 2), color1.substr(5, 2)].map(function (s) { return parseInt(s, 16); })
var end = color2.length === 4 ? color2.substr(1).split('').map(function (s) { return 0x11 * parseInt(s, 16); }) : [color2.substr(1, 2), color2.substr(3, 2), color2.substr(5, 2)].map(function (s) { return parseInt(s, 16); })
for (var n=rs;n<=re;n+=0.03){
ms = (n - rs) / (re - rs);
me = 1 - ms;
for (var j = 0; j < 3; j++){
so[j] = Math.round((start[j] * me + end[j] * ms)).toString(16);
so[j] = (so[j].length === 1) ? '0' + so[j] : so[j];
}
color = '#' + so.join('');
var s = -Math.sin(n);
var c = Math.cos(n);
context.save();
context.globalAlpha = 1;
context.beginPath();
context.fillStyle = color;
context.arc(x+(s*radius),y+(c*radius),borderW / 2,0,2*Math.PI, false);
context.fill();
context.restore();
}
}
2、修改drawArcbarDataPoints函数
function drawArcbarDataPoints(series, opts, config, context) {
var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
var arcbarOption = assign({}, {
startAngle: 0.75,
endAngle: 0.25,
type: 'default',
width: 12 * opts.pix,
gap: 2 * opts.pix,
linearType: 'none',
customColor: [],
}, opts.extra.arcbar);
series = getArcbarDataPoints(series, arcbarOption, process);
var centerPosition;
if (arcbarOption.centerX || arcbarOption.centerY) {
centerPosition = {
x: arcbarOption.centerX ? arcbarOption.centerX : opts.width / 2,
y: arcbarOption.centerY ? arcbarOption.centerY : opts.height / 2
};
} else {
centerPosition = {
x: opts.width / 2,
y: opts.height / 2
};
}
var radius;
if (arcbarOption.radius) {
radius = arcbarOption.radius;
} else {
radius = Math.min(centerPosition.x, centerPosition.y);
radius -= 5 * opts.pix;
radius -= arcbarOption.width / 2;
}
arcbarOption.customColor = fillCustomColor(arcbarOption.linearType, arcbarOption.customColor, series, config);
for (let i = 0; i < series.length; i++) {
let eachSeries = series[i];
//背景颜色
if(process == 0){ //仅第1次画背景颜色
context.setLineWidth(arcbarOption.width);
context.setStrokeStyle(arcbarOption.backgroundColor || '#E9E9E9');
context.setLineCap('round');
context.beginPath();
if (arcbarOption.type == 'default') {
context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width + arcbarOption.gap) * i, arcbarOption.startAngle * Math.PI, arcbarOption.endAngle * Math.PI, false);
} else {
context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width + arcbarOption.gap) * i, 0, 2 * Math.PI, false);
}
context.stroke();
}
//进度条
var fillColor = eachSeries.color
var colorPercentage = eachSeries.colorPercentage || [];
if(colorPercentage.length > 1){
//渐变色处理(按照实际百分比展示颜色),起始百分比为上一次结束的进度, 结束百分比为当前process
var perColorLen = (eachSeries.percentageMax || 1) / (colorPercentage.length - 1);
//开始颜色
var curPer = eachSeries.data * eachSeries._process_last;
var idxS = parseInt(curPer / perColorLen);
var idxE = idxS + 1;
idxS = idxS >= colorPercentage.length ? colorPercentage.length - 1 : idxS;
idxE = idxE >= colorPercentage.length ? colorPercentage.length - 1 : idxE;
var color1 = getMixColor(colorPercentage[idxS], colorPercentage[idxE], (curPer - idxS * perColorLen) / perColorLen);
console.log('color1', color1)
//结束颜色
curPer = eachSeries.data * process;
idxS = parseInt(curPer / perColorLen);
idxE = idxS + 1;
idxS = idxS >= colorPercentage.length ? colorPercentage.length - 1 : idxS;
idxE = idxE >= colorPercentage.length ? colorPercentage.length - 1 : idxE;
console.log('color2', curPer + "," + idxS + "," + idxE + "," + perColorLen)
var color2 = getMixColor(colorPercentage[idxS], colorPercentage[idxE], (curPer - idxS * perColorLen) / perColorLen);
drawArcbarLinear(opts,config,context,centerPosition.x, centerPosition.y,radius - (arcbarOption.width + arcbarOption.gap) * i,eachSeries._proportion_last, eachSeries._proportion_ , arcbarOption.width, color1,color2)
//同步改变主标题字体颜色
opts.title.color = color2;
}else if(arcbarOption.linearType == 'arc'){
//渐变色处理(无论进度多长,都是从对应series设置的color颜色,到customColor中对应series的结束颜色)
//根据加载的百分比计算渐变开始颜色和结束颜色
var color1 = getMixColor(eachSeries.color, arcbarOption.customColor[eachSeries.linearIndex], eachSeries._process_last)
var color2 = getMixColor(eachSeries.color, arcbarOption.customColor[eachSeries.linearIndex], eachSeries._process_)
drawArcbarLinear(opts,config,context,centerPosition.x, centerPosition.y,radius - (arcbarOption.width + arcbarOption.gap) * i,eachSeries._proportion_last, eachSeries._proportion_ , arcbarOption.width, color1,color2)
}else{
if(arcbarOption.linearType == 'custom'){
var grd = context.createLinearGradient(centerPosition.x - radius, centerPosition.y, centerPosition.x + radius, centerPosition.y);
grd.addColorStop(1, hexToRgb(arcbarOption.customColor[eachSeries.linearIndex], 1))
grd.addColorStop(0, hexToRgb(eachSeries.color, 1))
fillColor = grd;
}
context.setLineWidth(arcbarOption.width);
context.setStrokeStyle(fillColor);
context.setLineCap('round');
context.beginPath();
context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width + arcbarOption.gap) * i, arcbarOption.startAngle * Math.PI, eachSeries._proportion_ * Math.PI, false);
context.stroke();
}
}
//只有1个序列,且主标题包含%时,动态显示百分比
var oriName = opts.title.oriName || opts.title.name;
if(series.length == 1 && oriName.slice(-1) == '%'){
var dotN = oriName.match(/\.\d{1,}/)
dotN = !dotN ? 0 : dotN[0].length - 1;
opts.title.oriName = oriName;//记录原始标题,保证process=1时完美还原展示
opts.title.name = process === 1 ? opts.title.oriName : (((series[0].data * process) * 100).toFixed(dotN) + '%')
opts.stepClear=1;//别忘记这一步
clearArc(opts, context, centerPosition.x, centerPosition.y, radius - (arcbarOption.width + arcbarOption.gap)-2);
}
drawRingTitle(opts, config, context, centerPosition);
return {
center: centerPosition,
radius: radius,
series: series
};
}
3、修改drawCharts函数中对于arcbar的处理
//将 case 'arcbar':
//中 onProcess 函数里面,clearRect的调用,改为只在process == 0 时才处理
process == 0 && context.clearRect(0, 0, opts.width, opts.height);
4、修改函数getArcbarDataPoints
将函数中,如下语句
item._proportion_ = totalAngle * item.data * process + arcbarOption.startAngle;
修改为
item._process_last = item._process_ || 0;
item._process_ = process || 0;
item._proportion_last = item._proportion_ || arcbarOption.startAngle;
item._proportion_ = totalAngle * item.data * process + arcbarOption.startAngle;
5、弧形渐变调用方法
...
//arcbar中的linearType传入arc即可,其中customColor不传,则默认使用uchart的config中的默认颜色方案
{arcbar: {...,linearType:'arc',customColor:['#2fc25b']}}
...
6、进度渐变调用方法
...
//不同series支持使用不同的颜色方案,只需要为序列传入 colorPercentage 参数即可,
//需要多少中颜色就传入几个颜色值,其中第一个颜色值表示 0% 时的颜色,
//最后一个颜色值表示 100% * percentageMax 时的颜色,
//中间的按照颜色个数等分,超过 100% * percentageMax 时超过部分使用最后一个颜色值
//(percentageMax 表示颜色百分比终止位置,1为100%,2为200%...默认为1)
series: [{name: "完成率", data: 0.89, color: '这里可以不传入值', colorPercentage:['#f04864','#ffaa00','#2fc25b'], percentageMax:1}]
...
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
登录 后才可以发表评论