扇形图
<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:18.97.14.86,2025-01-17 06:59:12,Processed in 0.01578 second(s).