@alicloud/cloud-charts
Version:

375 lines (369 loc) • 15.6 kB
JavaScript
import themes from '../themes/index';
var DashBoard = /*#__PURE__*/function () {
function DashBoard(selector, options) {
this.element = typeof selector === 'string' ? document.querySelector(selector) : selector;
this.options = Object.assign(this.defaultOptions || {}, options || {});
this.data = 0;
this.oldData = 0;
this["default"] = {
padding: 80,
//总空余
lineWidth: 1,
//刻度表的线宽
counterClockwise: false,
//画圆方向
startAngle: 0.25 * Math.PI,
//圆环起始角度
endAngle: 0.75 * Math.PI,
//圆环终止角度
valueAngle: 0.25 * Math.PI,
//默认值0的角度,
timerCount: 0,
//计时器状态
tempData: 0,
//动画过渡值
timer: "",
//计时器
valueColor: ""
};
this.defaultOptions = {
text: '',
//仪表盘内部文案,不能与指针共存
textColor: themes.colorBlack,
//仪表盘内部文案
textInDashboard: false,
//是否在仪表盘内部显示文案
textSize: 12,
url: "",
urlLength: 60,
//icon长宽
urlBottom: 30,
// textLength: 20,//文字长度
radius: 135,
//刻度表线半径
dialRadius: 165,
//刻度盘圆环外半径
blankAngle: 0 * Math.PI,
//刻度盘空余角度
angle: 1.5 * Math.PI,
//刻度盘角度(包括空余角度)
boardFontColor: themes.colorText12,
//刻度盘字体颜色
boardFontSize: 12,
//刻度盘字体大小
borderColor: themes.colorTransparent,
//刻度表线颜色
pointerColor: themes.colorText12,
//刻度线颜色
valuePartColor: themes.colorB16,
//值域颜色
maxPartColor: themes.colorFill12,
//刻度盘圆环
maxValueColor: themes.colorTransparent,
//最大值标记颜色
pointOutColor: themes.colorTransparent,
// 值域刻度颜色
currentValueColor: themes.colorTransparent,
//当前值刻度线颜色
pointerOutterWidth: 8,
// 指针包含的外圆半径
pointerWidth: 90,
// 指针针尖相对于圆心半径
pointerAngle: 0.6 * Math.PI,
// 指针两边与圆心角度
pointerPartColor: themes.colorB16,
// 指针颜色
pointerAreaWidth: 0,
pointerAreaColor: themes.colorTransparent,
dialWidth: 20,
//刻度盘圆环宽度
range: [0, 100],
//取值范围,值域
pointCount: 6,
//刻度点 数量
// pointOutCount: 8,//外部刻度点 数量
transitionDuration: 300,
//过度动画时间
isShowMax: true,
//是否有最大值标记
maxValue: 0,
maxValueLineWidth: 2,
//最大值刻度线宽
width: '',
//canvas width
height: '' //canvas height ,
};
this.options = Object.assign(this.defaultOptions, this.options);
if (this.element) {
this.init();
}
}
var _proto = DashBoard.prototype;
_proto.init = function init() {
var self = this;
this.data = this.options.range[0];
//仪表盘
var canvas = this.element.appendChild(document.createElement("canvas"));
canvas.height = this.options.radius * (1 + Math.sin((this.options.angle - Math.PI) / 2)) + this["default"].padding + this["default"].lineWidth;
canvas.width = this.options.radius * 2 + this["default"].padding + this["default"].lineWidth;
if (this.options.height) {
canvas.style.transform = "scale(" + this.options.height / canvas.height + ")";
}
if (this.options.width) {
canvas.style.transform = "scale(" + this.options.width / canvas.width + ")";
}
this.context = canvas.getContext('2d');
this["default"].x = canvas.width / 2;
this["default"].y = canvas.width / 2;
this.radius = this["default"].x - this["default"].padding / 2 - this["default"].lineWidth / 2;
this["default"].startAngle = this["default"].valueAngle = Math.PI - (this.options.angle - Math.PI) / 2;
this["default"].endAngle = (this.options.angle - Math.PI) / 2;
this.drawDashBoard(this.data);
this.drawIcon();
};
_proto.drawIcon = function drawIcon() {
if (this.options.url) {
var pastImg = this.element.querySelector('.icon-img');
if (pastImg) pastImg.remove();
var img = document.createElement("img");
img.src = this.options.url;
img.className = "icon-img";
img.style.position = "absolute";
img.style.width = this.options.urlLength + "px";
img.style.height = this.options.urlLength + "px";
img.style.left = 0;
img.style.right = 0;
img.style.margin = "auto";
img.style.bottom = this.options.urlBottom + "px";
this.element.appendChild(img);
}
};
_proto.changeColor = function changeColor(color) {
var result = color;
if (Array.isArray(color)) {
result = this.context.createLinearGradient(0, 0, this.options.dialRadius * 2, 0);
color.forEach(function (item, index) {
result.addColorStop(Number(index), item);
});
}
return result;
};
_proto.drawDashBoard = function drawDashBoard(data) {
var self = this;
//刻度表 线
var percent = (data - this.options.range[0]) / (this.options.range[1] - this.options.range[0]);
var endAngle = percent * (this.options.angle - this.options.blankAngle) + this["default"].startAngle + this.options.blankAngle / 2;
this.arcDraw(this.radius, this["default"].startAngle, this["default"].endAngle, this["default"].lineWidth, this.options.borderColor);
//值域0以下部分
var valuePartColor = this.changeColor(this.options.valuePartColor);
this.arcDraw(this.options.dialRadius - this.options.dialWidth / 2, this["default"].startAngle, this["default"].startAngle + this.options.blankAngle / 2, this.options.dialWidth, valuePartColor);
var maxPartColor = this.changeColor(this.options.maxPartColor);
this.arcDraw(this.options.dialRadius - this.options.dialWidth / 2, this["default"].startAngle, endAngle, this.options.dialWidth, valuePartColor);
this.arcDraw(this.options.dialRadius - this.options.dialWidth / 2, endAngle, this["default"].endAngle, this.options.dialWidth, maxPartColor);
if (this.options.isShowMax) {
this.options.maxValue = this.options.maxValue > this.options.range[1] ? this.options.range[1] : this.options.maxValue;
this.valueDraw(this.options.maxValue, false, this.options.maxValueColor);
}
//刻度表 点
this.pointDraw(this.options.pointCount, 0, 10, this.options.radius, this.options.pointerColor, true);
this.pointDraw(this.options.pointCount, 0, this.options.dialWidth, this.options.dialRadius - this.options.dialWidth / 2, this.options.pointOutColor);
if (this.options.text) {
this.writeText(this.options.text, this.options.unit, this.options.url);
} else {
//刻度指针
this.arcDraw(this.options.pointerOutterWidth, 0, 2 * Math.PI, 1, this.options.pointerPartColor, true);
this.pointerDraw(data); // 指针中心点
this.arcDraw(this.options.pointerAreaWidth, 0, 2 * Math.PI, 1, this.options.pointerPartColor, true, "" + this.options.pointerAreaColor);
}
};
_proto.arcDraw = function arcDraw(radius, startAngle, endAngle, lineWidth, color, isfill, fillColor) {
this.context.beginPath();
this.context.arc(this["default"].x, this["default"].y, radius, startAngle, endAngle, this["default"].counterClockwise);
this.context.lineWidth = lineWidth;
this.context.strokeStyle = color;
this.context.stroke();
if (isfill) {
this.context.save();
this.context.fillStyle = fillColor || color;
this.context.fill();
this.context.restore();
}
}
//画值线
;
_proto.pointLineDraw = function pointLineDraw(A, pointerLength, R, color) {
var Rmax = R + pointerLength / 2;
var Rmin = R - pointerLength / 2;
var X = this["default"].x;
var Y = this["default"].y;
this.context.beginPath();
this.context.moveTo(X - Rmin * Math.cos(A), Y - Rmin * Math.sin(A));
this.context.lineTo(X - Rmax * Math.cos(A), Y - Rmax * Math.sin(A));
this.context.lineWidth = 2;
this.context.strokeStyle = color;
this.context.closePath();
this.context.stroke();
}
//画刻度,刻度坐标公式(X-R*Math.cos(A) ,Y-R*sin(A))
;
_proto.pointDraw = function pointDraw(number, start, pointerLength, R, color, isText) {
for (var i = start; i < number; i++) {
var A = i / (number - 1) * (this.options.angle - this.options.blankAngle) + this["default"].startAngle - Math.PI + this.options.blankAngle / 2;
var Rmax = R + pointerLength / 2;
var Rmin = R - pointerLength / 2;
var X = this["default"].x;
var Y = this["default"].y;
var tx = X - (Rmin - this.options.boardFontSize) * Math.cos(A);
var ty = Y - (Rmin - this.options.boardFontSize) * Math.sin(A);
var text = i != number - 1 ? i / (number - 1) * (this.options.range[1] - this.options.range[0]) + this.options.range[0] : '∞';
this.context.beginPath();
this.context.moveTo(X - Rmin * Math.cos(A), Y - Rmin * Math.sin(A));
this.context.lineTo(X - Rmax * Math.cos(A), Y - Rmax * Math.sin(A));
this.context.lineWidth = 1;
this.context.strokeStyle = color;
this.context.closePath();
this.context.stroke();
if (isText) {
this.writeFontText(tx, ty, A - Math.PI / 2, text); //画刻度字
}
}
}
//仪表盘内部文案
;
_proto.writeText = function writeText(text, unit, url) {
var textSize = Number(this.options.textSize);
var yArr = [this["default"].y + textSize, this["default"].y + 2 * textSize];
if (!url) yArr = [this["default"].y, this["default"].y + Number(textSize)];
this.context.save();
this.context.textAlign = "center";
this.context.fillStyle = this.options.textColor;
this.context.font = textSize + ("px " + themes['widgets-font-family-txd-m-number']);
this.context.fillText(text, this["default"].x, yArr[0]);
this.context.restore();
this.context.save();
this.context.textAlign = "center";
this.context.fillStyle = this.options.unitColor;
this.context.font = this.options.unitSize + ("px " + themes['widgets-font-family-txd-m-number']);
this.context.fillText(unit, this["default"].x, yArr[1]);
this.context.restore();
};
_proto.writeFontText = function writeFontText(tx, ty, A, text) {
this.context.save();
// if (text == '∞') {
// tx += 10;
// } else if (text == this.options.range[0]) {
// tx -= 10;
// } else {
this.context.translate(tx, ty);
this.context.rotate(A);
this.context.translate(-tx, -ty);
// }
if (text >= 10000) {
text = text / 10000 + "W";
}
this.context.textAlign = "center";
this.context.fillStyle = this.options.boardFontColor;
this.context.font = this.options.boardFontSize + ("px " + themes['widgets-font-family-txd-m-number']);
this.context.fillText(text, tx, ty);
this.context.restore();
}
//标值,可以选择在标记在刻度盘还是刻度表上,坐标公式(X-R*Math.cos(A) ,Y-R*sin(A))
;
_proto.valueDraw = function valueDraw(data, isInDial, color) {
var A = (data - this.options.range[0]) / (this.options.range[1] - this.options.range[0]) * (this.options.angle - this.options.blankAngle) + this["default"].startAngle - Math.PI + this.options.blankAngle / 2;
var dialWidth, Rmax, Rmin;
var X = this["default"].x;
var Y = this["default"].y;
var valueColor = this.changeColor(this.options.valuePartColor);
if (isInDial) {
dialWidth = 10; //线长度
Rmax = this.radius + dialWidth / 2;
Rmin = this.radius - dialWidth / 2;
} else {
Rmax = this.options.dialRadius;
Rmin = this.options.dialRadius - this.options.dialWidth;
}
if (color) {
valueColor = color;
}
this.context.beginPath();
this.context.moveTo(X - Rmin * Math.cos(A), Y - Rmin * Math.sin(A));
this.context.lineTo(X - Rmax * Math.cos(A), Y - Rmax * Math.sin(A));
this.context.lineWidth = this.options.maxValueLineWidth;
this.context.strokeStyle = valueColor;
this.context.closePath();
this.context.stroke();
}
//画指针
;
_proto.pointerDraw = function pointerDraw(value) {
var A = (value - this.options.range[0]) / (this.options.range[1] - this.options.range[0]) * (this.options.angle - this.options.blankAngle) + this["default"].startAngle - Math.PI + this.options.blankAngle / 2;
var a = this.options.pointerAngle;
var X = this["default"].x;
var Y = this["default"].y;
this.context.save();
this.context.beginPath();
this.context.moveTo(X - this.options.pointerOutterWidth * Math.cos(A - a / 2), Y - this.options.pointerOutterWidth * Math.sin(A - a / 2));
this.context.lineTo(X - this.options.pointerWidth * Math.cos(A), Y - this.options.pointerWidth * Math.sin(A));
this.context.lineTo(X - this.options.pointerOutterWidth * Math.cos(A + a / 2), Y - this.options.pointerOutterWidth * Math.sin(A + a / 2));
this.context.lineTo(X - this.options.pointerOutterWidth * Math.cos(A), Y - this.options.pointerOutterWidth * Math.sin(A));
this.context.lineWidth = 2;
this.context.fillStyle = this.options.pointerPartColor;
this.context.fill();
this.context.restore();
};
_proto.getData = function getData() {
return this.data;
};
_proto.setData = function setData(data, sync) {
if (typeof data === 'number') {
this.data = Object.assign(this.data, data);
this.oldData = this.data;
var little = (this.options.range[1] - this.options.range[0]) / 200000;
this.data = data > this.options.range[1] ? this.options.range[1] - little : data < this.options.range[0] ? this.options.range[0] : data; //Object.assign(this.data,data);
//console.log(this.data)
sync = sync === undefined ? true : sync;
if (sync) this.render();
}
};
_proto.addData = function addData(data, shift) {
data = Array.isArray(data) ? data : [data];
this.data = this.data.concat(data);
if (shift) this.data.splice(0, data.length);
this.render();
};
_proto.getOption = function getOption(key) {
if (key) return this.options[key];else return this.options;
};
_proto.setOption = function setOption(options, sync) {
sync = sync === undefined ? true : sync;
Object.assign(this.options, options);
if (sync) this.render();
};
_proto.animate = function animate() {
//requestAnimationFrame( self.animate.bind(self) );
var self = this;
if (self["default"].timer) {
self.oldData = self["default"].tempData;
clearInterval(self["default"].timer);
}
var width = self.options.radius * 2 + self["default"].padding + self["default"].lineWidth;
var animateMove = function animateMove() {
if (self["default"].timerCount <= 50) {
self.context.clearRect(0, 0, width, width);
self["default"].tempData = self["default"].timerCount / 50 * (self.data - self.oldData) + self.oldData;
self.drawDashBoard(self["default"].tempData);
self["default"].timerCount = self["default"].timerCount + 1;
} else {
clearInterval(self["default"].timer);
}
};
self["default"].timer = setInterval(animateMove, self.options.transitionDuration / 50);
};
_proto.render = function render() {
this["default"].timerCount = 0;
this.animate();
};
return DashBoard;
}();
export default DashBoard;