扇形图
<canvas id="j_canvas" width="300" height="300"></canvas>
<script type="text/javascript">
function drawSector(opt) {
var target = document.getElementById(opt.id),
ctx = target.getContext('2d'),
pers = opt.pers,
n = 0,
len = pers.length,
w = target.width, // 使用 target.width 获取画布宽度
s = 0,
e = 0;
ctx.clearRect(0, 0, w, w); // 清除之前的图形
for (; n < len; n++) {
ctx.beginPath();
var startAngle = Math.PI * 2 * s;
var endAngle = Math.PI * 2 * (s + Number(pers[n]));
ctx.arc(w / 2, w / 2, w / 2, startAngle, endAngle, false);
// 创建线性渐变填充
var gradient = ctx.createLinearGradient(0, 0, w, 0);
gradient.addColorStop(0, lightenColor(opt.colors[n], 0.7)); // 起始颜色,更浅色
gradient.addColorStop(1, opt.colors[n]); // 终止颜色,原始颜色
ctx.fillStyle = gradient;
ctx.lineTo(w / 2, w / 2);
ctx.fill();
// 计算百分比文本位置并绘制
var midAngle = (startAngle + endAngle) / 2;
var textRadius = w / 4; // 使用较小的半径使文本在扇形中间
var percentValue = (pers[n] * 100).toFixed(0) + '%';
var textX = w / 2 + textRadius * Math.cos(midAngle);
var textY = w / 2 + textRadius * Math.sin(midAngle);
ctx.fillStyle = 'black'; // 文本颜色为黑色
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(percentValue, textX, textY);
// 更新起始角度
s += Number(pers[n]);
}
}
function lightenColor(color, percent) {
// 将颜色转换为 RGB 格式
color = color.substring(1); // 去掉 #
var rgb = parseInt(color, 16);
var r = (rgb >> 16) & 0xff;
var g = (rgb >> 8) & 0xff;
var b = (rgb >> 0) & 0xff;
// 调整每个颜色通道
r = Math.round(r * (1 - percent) + 255 * percent);
g = Math.round(g * (1 - percent) + 255 * percent);
b = Math.round(b * (1 - percent) + 255 * percent);
// 转换回十六进制颜色
return '#' + (r << 16 | g << 8 | b).toString(16).padStart(6, '0');
}
function updateChart() {
var colors = ['#259', '#333', '#f60', '#999'];
var data = [
['0.2', '0.4', '0.3', '0.1'],
['0.1', '0.5', '0.2', '0.2'],
['0.3', '0.3', '0.2', '0.2']
];
var index = new Date().getSeconds() % data.length; // 随机选择数据组
drawSector({'id':'j_canvas', 'colors': colors, 'pers': data[index]});
}
// 初次绘制
updateChart();
// 每2秒更新一次
setInterval(updateChart, 2000);
</script>
走形图
<div class="ui-fill">
<canvas id="demo" width="400" height="400"></canvas>
<div class="score-legend">
<span style="color: #259;">● Line 1</span>
<span style="color: #f60;">● Line 2</span>
<span style="color: #333;">● Line 3</span>
</div>
</div>
<script type="text/javascript">
var target = document.getElementById('demo');
var pic = target.getContext('2d');
// 参数
var canvasWidth = 400,
canvasHeight = 400,
margin = 30; // 留出边界
// 画线
function drawContLine(opt) {
pic.beginPath();
var path = opt.path,
color = opt.color;
pic.moveTo(path[0][0], path[0][1]);
var n = 1, len = path.length;
for (; n < len; n++) {
pic.lineTo(path[n][0], path[n][1]);
}
pic.lineWidth = 2;
pic.strokeStyle = color;
pic.stroke();
pic.closePath();
}
// 绘制坐标轴和刻度
function drawAxis(maxValue) {
pic.beginPath();
// 绘制垂直坐标轴
pic.moveTo(margin, margin);
pic.lineTo(margin, canvasHeight - margin + 10); // 加10确保刻度线完整显示
// 绘制水平坐标轴
pic.moveTo(margin - 10, canvasHeight - margin);
pic.lineTo(canvasWidth - margin + 10, canvasHeight - margin);
// 绘制坐标轴刻度
var scale = (canvasHeight - 2 * margin) / 5;
for (var i = 0; i <= 5; i++) {
// 垂直刻度线
var y = margin + i * scale;
pic.moveTo(margin, y);
pic.lineTo(margin - 5, y);
// 显示垂直刻度值
pic.fillText((maxValue - i * (maxValue / 5)).toFixed(0), margin - 20, y + 5);
// 水平刻度线
var x = margin + i * (canvasWidth - 2 * margin) / 5;
pic.moveTo(x, canvasHeight - margin);
pic.lineTo(x, canvasHeight - margin + 10);
// 显示水平刻度值
pic.fillText((i * 20).toString(), x - 10, canvasHeight - margin + 25);
}
pic.strokeStyle = '#ccc';
pic.stroke();
pic.closePath();
}
// 计算最大值并确保为整十位数
function calculateMaxValue() {
var maxValues = dataGroups.map(function(group) {
return Math.max(...group.scores);
});
return Math.ceil(Math.max(...maxValues) / 10) * 10; // 向上取整到最近的十位数
}
// 分数转化为坐标输出
function transforCoor(opt) {
var scores = opt.scores,
maxVal = opt.maxVal,
n = 0,
len = scores.length,
a_path = [];
for (; n < len; n++) {
var x = margin + n * ((canvasWidth - 2 * margin) / 5);
var y = margin + ((scores[n] / maxVal) * (canvasHeight - 2 * margin));
var arry = [x, y];
a_path.push(arry);
}
drawContLine({'path': a_path, 'color': opt.color});
}
// 数据组
var dataGroups = [
{'scores': [300, 80, 300, 70, 700], 'color': '#259', 'name': 'Line 1'},
{'scores': [400, 86, 400, 84, 800], 'color': '#f60', 'name': 'Line 2'},
{'scores': [500, 87, 500, 86, 900], 'color': '#333', 'name': 'Line 3'}
];
// 更新图表
function updateChart() {
// 更新数据前先计算新的最大值
var maxValue = calculateMaxValue();
pic.clearRect(0, 0, canvasWidth, canvasHeight); // 清除之前的图形
drawAxis(maxValue); // 重新绘制坐标轴
// 更新每组数据
for (var i = 0; i < dataGroups.length; i++) {
// 移动数据
dataGroups[i].scores.unshift(Math.floor(Math.random() * 91) + 10); // 添加新的随机元素到数组开头
dataGroups[i].scores.pop(); // 移除数组的最后一个元素
transforCoor({'scores': dataGroups[i].scores, 'maxVal': maxValue, 'color': dataGroups[i].color});
}
}
// 初次绘制
updateChart();
// 每2秒更新一次
setInterval(updateChart, 2000);
</script>
Powered by ddoss.cn 12.0
©2015 - 2025 ddoss
渝公网安备50011302222260号
渝ICP备2024035333号
【实验平台安全承诺书】
小绿叶技术社区,优化网络中,点击查看配置信息
主机监控系统: 安全防火墙已开启检查cc攻击-下载文件完成后等待10s 恢复访问,检查连接数低于峰值恢复访问
您的IP:216.73.216.110,2025-12-01 14:24:29,Processed in 0.01574 second(s).