SOURCE

console 命令行工具 X clear

                    
>
console
//数据
let obj={
	"tagName": "交易活跃度特征",
	"tagValues": ["理财","借贷"],
	"tagUUID": "CT_TRAD_ACTIVE",
	"tagValueUUIDs": ["CT_TRAD_ACTIVE_FINANCE","CT_TRAD_ACTIVE_DEBIT"],
	"allTagValues": ["借贷",
	"卡消费",
	"分期",
	"资金转出",
	"资金转入",
	"理财"],
	"allTagValusUUIDs": ["CT_TRAD_ACTIVE_DEBIT",
	"CT_TRAD_ACTIVE_CARD",
	"CT_TRAD_ACTIVE_INSTAL",
	"CT_TRAD_ACTIVE_TRANSOUT",
	"CT_TRAD_ACTIVE_TRANSIN",
	"CT_TRAD_ACTIVE_FINANCE"]
}	
let obj1={
	"tagName": "消费特征",
	"tagValues": ["美食家","月光一族","网购达人","有车一族","购物达人"],
	"tagUUID": "CT_TRAD_CONSUME",
	"tagValueUUIDs": ["CT_TRAD_CONSUME_EAT","CT_TRAD_CONSUME_MOONLIGHT","CT_TRAD_CONSUME_ONLINE","CT_TRAD_CONSUME_CAR","CT_TRAD_CONSUME_SHOP"],
	"allTagValues": ["美食家",
	"奢侈品爱好者",
	"商旅人士",
	"艺术品收藏家",
	"娱乐达人",
	"购物达人",
	"有车一族",
	"刷卡达人",
	"网购达人",
	"月光一族"],
	"allTagValusUUIDs": ["CT_TRAD_CONSUME_EAT",
	"CT_TRAD_CONSUME_LUXURY",
	"CT_TRAD_CONSUME_BUSINESS",
	"CT_TRAD_CONSUME_ART",
	"CT_TRAD_CONSUME_ENTERTAIN",
	"CT_TRAD_CONSUME_SHOP",
	"CT_TRAD_CONSUME_CAR",
	"CT_TRAD_CONSUME_CARD",
	"CT_TRAD_CONSUME_ONLINE",
	"CT_TRAD_CONSUME_MOONLIGHT"]
}
		

let obj2={
	"tagName": "持有产品偏好",
	"tagValues": ["活期","保险","基金"],
	"tagUUID": "CT_PREF_PROD",
	"tagValueUUIDs": ["CT_PREF_PROD_DEPOSIT","CT_PREF_PROD_CURRENT","CT_PREF_PROD_FINANCE"],
	"allTagValues": ["活期",
	"保险",
	"理财",
	"基金",
	"国债",
	"定期"],
	"allTagValusUUIDs": ["CT_PREF_PROD_DEPOSIT",
	"CT_PREF_PROD_CURRENT",
	"CT_PREF_PROD_INSURAN",
	"CT_PREF_PROD_FINANCE",
	"CT_PREF_PROD_FUND",
	"CT_PREF_PROD_BOND"]
}	

let obj3={
	"tagName": "交易类型偏好",
	"tagValues": ["消费","取现","转账"],
	"tagUUID": "CT_PREF_TRAD",
	"tagValueUUIDs": ["CT_PREF_TRAD_CONSUME","CT_PREF_TRAD_CASH","CT_PREF_TRAD_TRANSFER"],
	"allTagValues": ["消费",
	"取现",
	"转账",
	"查询"],
	"allTagValusUUIDs": ["CT_PREF_TRAD_CONSUME",
	"CT_PREF_TRAD_CASH",
	"CT_PREF_TRAD_TRANSFER",
	"CT_PREF_TRAD_INQUERY"]
}

class drawFeature{	
	
	constructor(obj,id){
		this.data = obj; //获取数据	
		this.colors = {
			//线条颜色,内圆填充色,弧线条色,填充色
			'CT_TRAD_ACTIVE':['#A0DBF2','#F3FCFF','#44BBE7','rgba(68,187,230,0.5)'],
			'CT_TRAD_CONSUME':['#C3E493','#EFFBDE','#8ECA36','rgba(149,205,66,0.7)'],
			'CT_PREF_PROD':['#FDEEA9','#FFF7D8','#FFC803','rgba(255,227,128,0.5)'],
			'CT_PREF_TRAD':['#DBE2FE','#F8F9FE','#7C97E4','rgba(185,200,241,0.5)']
		}		
		//选用样式
		this.activeStyle = {			
			'round':{
			  starAngle:0,   //起始角度
			  endAngle:360,  //结束角度
			  anticlockwise:true,  //默认顺时针
			  radius:75,     //半径
			  border:[1,this.colors[this.data.tagUUID][0]],   //边框宽度值,颜色
			  bgColor:'#fff'  //背景色
			},
			'dashround_1':{
			  step:5,        //虚线间距
			  starAngle:0,   //起始角度
			  endAngle:360,  //结束角度
			  anticlockwise:true,  //默认顺时针
			  radius:60,     //半径
			  border:[1,this.colors[this.data.tagUUID][0]],   //边框宽度值,颜色
			  bgColor:'#fff',  //背景色
			  innerBorder:[0,'#fff'],  //内环边框
			  innerBgColor:this.colors[this.data.tagUUID][1]     //内环背景色
			},
			'dashround_2':{
			  step:10,        //虚线间距
			  starAngle:0,   //起始角度
			  endAngle:360,  //结束角度
			  anticlockwise:true,  //默认顺时针
			  radius:45,     //半径
			  border:[1,this.colors[this.data.tagUUID][0]],   //边框宽度值,颜色
			  bgColor:'#fff',  //背景色
			  innerBorder:[0,'#fff'],  //内环边框
			  innerBgColor:'#fff'     //内环背景色
			},
			'dashround_3':{
			  step:15,        //虚线间距
			  starAngle:0,   //起始角度
			  endAngle:360,  //结束角度
			  anticlockwise:true,  //默认顺时针
			  radius:30,     //半径
			  border:[1,this.colors[this.data.tagUUID][0]],   //边框宽度值,颜色
			  bgColor:'#fff',  //背景色
			  innerBorder:[0,'#fff'],  //内环边框
			  innerBgColor:this.colors[this.data.tagUUID][1]     //内环背景色
			},
			'dashround_4':{
			  step:20,        //虚线间距
			  starAngle:0,   //起始角度
			  endAngle:360,  //结束角度
			  anticlockwise:true,  //默认顺时针
			  radius:15,     //半径
			  border:[1,this.colors[this.data.tagUUID][0]],   //边框宽度值,颜色
			  bgColor:'#fff',  //背景色
			  innerBorder:[0,'#fff'],  //内环边框
			  innerBgColor:'#fff'     //内环背景色
			},
			'screen':{   //弧
			  radius:60,
			  border:[2,this.colors[this.data.tagUUID][2]],
			  bgColor:this.colors[this.data.tagUUID][3]
			},
			'line':{
			  width:75,
			  border:[1,this.colors[this.data.tagUUID][0]]
			},
			'smallRound':{
			  starAngle:0,
			  endAngle:360,
			  radius:3,
			  fatherRadius:60,
			  border:[2,this.colors[this.data.tagUUID][2]],
			  noBorder:[2,'red'],
			  bgColor:'#fff'
			},
			'text':{
			  radius:90,                 //在外圆半径
			  font:'14px Arial',
			  color:'#465368',
			  noColor:'#BEC7D0',
			  offsetPosition:{x:0,y:3}   //偏移位置
			},
			'canvasStyle':{
			  border:[0,'#fff'], //边框宽度值,颜色
			  bgColor:'#fff',    //背景色
			}
		}	
		
		
		//创建canvas
		//let canvas = document.createElement('canvas');
		let canvas = document.getElementById(id);
		canvas.width = 300;
		canvas.height = 300;
		
		//获取绘图环境
		let ctx = canvas.getContext('2d');		
		if(!ctx) alert('浏览器不支持canvas,请升级浏览器');
		
		//获取中心坐标
		let centre = {x:canvas.width/2,y: canvas.height/2};
		//填充画布背景色
		this.drawRect(ctx,0,0,canvas.width,canvas.height,this.activeStyle.canvasStyle.border[0],this.activeStyle.canvasStyle.border[1],this.activeStyle.canvasStyle.bgColor);
		//画实线圆
		this.drawSolidRound(ctx, centre.x, centre.y,this.activeStyle.round);
		//画虚线圆
		this.drawDashRound(ctx,centre.x, centre.y,this.activeStyle.dashround_1);
		this.drawDashRound(ctx,centre.x, centre.y,this.activeStyle.dashround_2);
		this.drawDashRound(ctx,centre.x, centre.y,this.activeStyle.dashround_3);
		this.drawDashRound(ctx,centre.x, centre.y,this.activeStyle.dashround_4);
		//画等分线
		this.drawAngleSolid(ctx,centre.x,centre.y,this.activeStyle.line);
		//画弧描边
		this.drawMoreScreen(ctx);
		
		//画小圈圈		
		this.drawSmallCircle(ctx,centre.x, centre.y,this.activeStyle.smallRound);	
		//添加文字		
		this.drwaText(ctx,centre.x, centre.y,this.activeStyle.text);

		this.createImg = canvas.toDataURL("image/jpeg", 1);		
	}
	
	getCanvasImg(){
		return this.createImg;
	}
	
	//画实线圆  round
    drawSolidRound(ctx,x,y,round){
		ctx.beginPath()
		ctx.lineWidth = round.border[0];   
		ctx.strokeStyle = round.border[1]; 
		ctx.closePath();
		ctx.arc(x, y, round.radius, this.getRads(round.starAngle),this.getRads(round.endAngle),round.anticlockwise); 
		ctx.fillStyle = round.bgColor;
		ctx.fill();
		ctx.stroke();
	}
	//画虚线圆 dashround
	drawDashRound (ctx, x, y, dashround){    
		let step = dashround.step / 180 * 2 * Math.PI;
		for (let b = 0, e = step / 2; e <= dashround.endAngle; b += step, e += step) {
		  ctx.beginPath()
		  ctx.lineWidth = dashround.border[0];
		  ctx.strokeStyle = dashround.border[1];
		  ctx.closePath();
		  ctx.arc(x, y, dashround.radius, b, e);
		  ctx.stroke();
		}
		//填充内圈
		 ctx.beginPath()
		 ctx.lineWidth = dashround.innerBorder[0];
		 ctx.strokeStyle= dashround.innerBorder[1];
		 ctx.closePath();
		 ctx.arc(x, y, dashround.radius - dashround.border[0], this.getRads(dashround.starAngle), this.getRads(dashround.endAngle));
		 ctx.fillStyle= dashround.innerBgColor;
		 ctx.fill();
		 ctx.stroke();
	}
	//画等分线
	drawAngleSolid(ctx,x,y,line){
		//画等分线
		let s = {
			x:x,
			y:y,
			r:line.width
		}
		let num = this.data.allTagValues.length;   //获取等分
		let sang = this.getsolidPointAngle(num);   	
		let spoint = this.getCircle(s,sang);				
		
		ctx.lineWidth = line.border[0];
		ctx.strokeStyle = line.border[1];
		
		let nleng = spoint.length/2;
		for(let i=0;i<spoint.length/2;i++){
			ctx.beginPath();
			ctx.moveTo(spoint[i].x,spoint[i].y);
			ctx.lineTo(spoint[i+nleng].x,spoint[i+nleng].y);
			ctx.stroke();
			ctx.closePath();
		}
		
	}
	//多个弧度
	drawMoreScreen(ctx){
		let self = this;
		let screenArr = this.data.tagValueUUIDs;
		let allScreenArr = this.data.allTagValusUUIDs;
		let angle = 360 / allScreenArr.length;
		let angleArr = this.getsolidPointAngle(allScreenArr.length);
		let tmpArr = [];
		screenArr.forEach( val => {
			let tmpobj = this.isArrayValue(val,allScreenArr);
			if(tmpobj.flag){
				let ang = angleArr[tmpobj.ind];
				tmpArr.push(ang);
			}
		});				
		tmpArr.forEach( val =>{
			self.drawScreen(ctx,canvas.width,canvas.height,this.activeStyle.screen,this.getRads(val),this.getRads(val+angle));
		});
	}
	//画弧描边
	drawScreen (ctx,canvasWidth,canvasHeight,screen,sDeg,eDeg) { 
		let arc = { 
				x: canvasWidth / 2,
				y: canvasHeight / 2,
				r: screen.radius 
			}, 
			w = canvasWidth, 
			h = canvasHeight; 
			ctx.save(); 
			ctx.lineWidth = screen.border[0]; 	
			ctx.strokeStyle = screen.border[1];			
			ctx.fillStyle = screen.bgColor; 
			ctx.beginPath(); // 起始点设置在圆心处 
			ctx.moveTo(arc.x, arc.y);
			ctx.arc(arc.x, arc.y, arc.r,sDeg,eDeg); // 闭合路径
			ctx.closePath();
			ctx.fill();
			ctx.stroke();
	}	
	//画小圈圈
	drawSmallCircle(ctx,x,y,smallRound){
		let self = this;
		let c ={
			x:x,
			y:y,
			r:smallRound.fatherRadius
		}
		let num = this.data.allTagValues.length; //获取等分
		let angles = this.getAngles(num);	
		let quan = this.getCircle(c,angles);  //画小圈圈	
		
		quan.forEach(function(val){
			self.drawSolidRound(ctx,val.x,val.y,smallRound);
		});
	}
	//绘制矩形
    drawRect(cxt,x,y,width,height,BW,BC,fillColor){
        cxt.beginPath();
        cxt.moveTo(x,y);
        cxt.lineTo(x+width,y);
        cxt.lineTo(x+width,y+height);
        cxt.lineTo(x,y+height);
        cxt.closePath();

        cxt.lineWidth=BW;
        cxt.fillStyle=fillColor;
        cxt.strokeStyle=BC;

        cxt.fill();
        cxt.stroke();
    }	
	//绘文字
    drwaText(ctx,x,y,text){	
		let t = {
			x:x,
			y:y,
			r:text.radius
		}
		let divide = this.data.allTagValues.length;  //等分
		let angles = this.bbbb(divide);
		
		let points = this.getCircle(t,angles);
		
		//this.drawSmallCircle(ctx,2,points)
		//this.drawSolidRound(ctx,circle.x,circle.y,circle.r,0,360,{width:1,bgColor:'#000'});
		
		let tmpArr =  this.dealTextData(ctx,points,this.data.allTagValues,text.offsetPosition); //获取处理好的数据

		ctx.font = text.font;
		ctx.fillStyle = text.color;
		
		tmpArr.forEach(function(val){
			ctx.fillText(val.text, val.point.x, val.point.y);	
		});
		
	}
	
	//工具
	//获取弧度
    getRads (degrees) { return (Math.PI * degrees) / 180; } 
	//获取角度
    getDegrees (rads) { return (rads * 180) / Math.PI; }
	//获取角度等分
	getAngles(num){
		let angle = 360 / num;
		let tmpArr = [];
		for(let i=1;i<=num;i++){
			tmpArr.push(angle * i);
		}
		return tmpArr;
	}	
	//获取圆上任意一点坐标
    getCircle(circle,circleArr){		
		let tmpArr = [];			
		tmpArr = circleArr.map(function(val){
			let obj = {};
			obj.x = circle.x + circle.r * Math.cos(val * Math.PI / 180);
			obj.y = circle.y + circle.r * Math.sin(val * Math.PI / 180);
			return obj;
		});
		return tmpArr;
	}
	//获取等分线角度
    getsolidPointAngle(num){
		let angle = 360 / num;
		let tmpArr = [];
		for(let i=0;i<num;i++){
			tmpArr.push(i * angle - 90);
		}
		return tmpArr;	
	}
	//bbbb
    bbbb(num){
		let angle = 360 / num;
		let tmpArr = [];
		for(let i=0;i<num;i++){
			tmpArr.push(angle * i - 90 + angle/2 );
		}
		return tmpArr;
	}
	//处理文字数据
    dealTextData(ctx,points,textArr,offsetPosition){
		let tmpArr = [];
		textArr.forEach(function(val,ind){
			let obj = {};
			let textWidth = ctx.measureText(val).width;  //获取文本长度
			if(ind < textArr.length / 2){
				let point = {
						x: points[ind].x + offsetPosition.x,
						y: points[ind].y + offsetPosition.y
					};
				obj.text = val; 
				obj.point = point;
			}else{
				let point = {
						x: points[ind].x + offsetPosition.x - textWidth -20,
						y: points[ind].y + offsetPosition.y
					};
				obj.text = val; 
				obj.point = point;
			}
			tmpArr.push(obj);		
		});
		return tmpArr;		
	}
	//判读数组是否存在某个值
	isArrayValue(val,arr){
	  let obj = {
		  flag:false,
		  ind:null
	  }		
	  arr.forEach((v,i) =>{
		if(val == v) {
			obj.flag = true;
			obj.ind = i;
		}
	  });
	  return obj;
	}
	
}

let a = new drawFeature(obj,'canvas');
let b = new drawFeature(obj1,'canvas1');
let c = new drawFeature(obj2,'canvas2');
let d = new drawFeature(obj3,'canvas3');

console.log(d.getCanvasImg());
	<canvas id="canvas" ></canvas>
	<canvas id="canvas1" ></canvas>
	<canvas id="canvas2" ></canvas>
	<canvas id="canvas3" ></canvas>
html,body{
  background:#fff;
}
canvas{
	margin:50px;
}