最近参考各路大神的路子,写了个简易版的svg环图插件。只为达到UI图的要求。比较简陋。
fyy-pie.js
/*
* author:fyy
* date: 2020-05-14
* */
;(function(global) {
"use strict";
var svg;
var startPoints = []
var percentNew = 0
var M = function(el) {
this.el = typeof el === "string" ? document.querySelector(el) : el;
};
M.prototype = {
draw: function(options) {
var elWidth = this.el.offsetWidth;
var elHeight = this.el.offsetHeight;
svg = this.createSvgTag('svg', {
'width': elWidth + 'px',
'height': elHeight + 'px',
'viewBox': '0 0 '+ elWidth + ' ' + elHeight
});
this.el.appendChild(svg);
var circle = this.createSvgTag('circle', {
'fill': 'none',
'cx': elWidth/2,
'cy': elHeight/2,
'r': options.graphStyle.radius,
'stroke': '#f2f2f2',
'stroke-width': options.graphStyle.specialStrokeWidth
})
var centerText = this.createSvgTag('text', {
'fill': options.centerText.color,
'class': 'center-text',
'style': 'font-size:' + options.centerText.fontSize
})
centerText.innerHTML = options.centerText.text;
svg.appendChild(centerText);
svg.appendChild(circle);
document.getElementsByClassName('center-text')[0].setAttribute('x', elWidth/2 - centerText.getBBox().width/2)
document.getElementsByClassName('center-text')[0].setAttribute('y', elHeight/2 + centerText.getBBox().height/4)
var index = 0
var time = 0
var that = this
var timer = setInterval(function () {
index += 1
if (index >= options.data.length) {
clearInterval(timer)
}
that.show(options, index, options.graphStyle.specialStrokeWidth, options.graphStyle.strokeWidth, options.graphStyle.radius, [elWidth, elHeight])
}, time)
},
show: function (options, index, firstStrokeWidth, commonStrokeWidth, radius, svgViewport) {
var radian = 0;
var endPointX = 0;
var endPointY = 0;
var largeArcFlag = 0;
var arcLength = options.data[index-1][1] * 360 * Math.PI * radius / 180
if(index === 1) {
percentNew = options.data[index-1][1] * 360;
radian = percentNew * (Math.PI / 180)
endPointX = svgViewport[0]/2 + Math.sin(radian) * radius
endPointY = svgViewport[1]/2 - Math.cos(radian) * radius
if (radian > Math.PI) {
largeArcFlag = 1
} else { largeArcFlag = 0 }
this.createPath(options.data[index-1], percentNew, svgViewport[0]/2, svgViewport[0]/2 - radius,endPointX, endPointY, largeArcFlag, 1,
options.graphStyle.strokeColors[index-1], arcLength, firstStrokeWidth, radius)
} else {
percentNew = options.data[index-1][1] * 360 + percentNew;
radian = percentNew * (Math.PI / 180)
endPointX = svgViewport[0]/2 + Math.sin(radian) * radius
endPointY = svgViewport[1]/2 - Math.cos(radian) * radius
if (options.data[index-1][1] * 360 * (Math.PI / 180) > Math.PI) {
largeArcFlag = 1
} else { largeArcFlag = 0 }
this.createPath(options.data[index-1], percentNew, startPoints[0], startPoints[1], endPointX, endPointY, largeArcFlag, 1,
options.graphStyle.strokeColors[index-1], arcLength, commonStrokeWidth, radius)
}
startPoints = [endPointX, endPointY]
startPoints = [endPointX, endPointY]
},
createPath: function ( pathNm, percent, startPointX, startPointY, endPointX, endPointY, largeArcFlag, sweepFlag, color, arcLength, strokeWidth, radius) {
// sweepFlag:规定绘制顺时针方向绘制,还是逆时针方向绘制,1表示顺时针,0表示逆时针。
// 当弧度大于Math.PI时需要画大弧 largeArcFlag=1 else =0
if(startPointX) {
var path = this.createSvgTag('path', {
'class': 'path',
'fill': 'none',
'stroke': color,
'stroke-linecap': 'round',
'style': 'stroke-dasharray:' + arcLength + ';stroke-dashoffset:' + arcLength,
'stroke-width': strokeWidth,
'd': 'M' + startPointX +' '+ startPointY +
' A'+ radius+','+ radius +' ' + percent +' ' + largeArcFlag + ',' + sweepFlag +' ' + endPointX + ',' + endPointY
})
svg.appendChild(path);
}
},
createSvgTag: function(tagName, attributes) {
var tag = document.createElementNS('http://www.w3.org/2000/svg', tagName)
for (var attr in attributes) {
tag.setAttribute(attr, attributes[attr])
}
return tag
}
};
if (typeof module !== 'undefined' && module.exports) module.exports = M;
if (typeof define === 'function') define(function() { return M; });
global.FyyPie = M;
})(this);
html
var pie = new FyyPie('#svgPie');
var pathArr = [['path1', 0.15], ['path2', 0.2], ['path3', 0.05], ['path4', 0.45]]
var colors = ['#d4e9ff', '#3a8eee', '#01dfd1', '#c1d5e6']
var options = {
data: pathArr,
graphStyle: {
strokeColors: colors,
strokeWidth: 12,
specialStrokeWidth: 6,
radius: 80
},
centerText: {
text: '信件公示',
color: 'rgb(35,55,91)',
fontSize: '24'
},
}
pie.draw(options)