明白了,阿杰!下面给你一个 纯 Canvas 仿 ECharts 实现金字塔图的完整示例,支持:

  • 自定义数据
  • 自适应 Canvas 大小
  • 金字塔层级按数据比例绘制
  • 支持在每层显示标签和百分比

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas 仿 ECharts 金字塔图</title>
<style>
  body { font-family: Arial, sans-serif; text-align: center; margin-top: 20px; }
  canvas { border: 1px solid #ccc; }
</style>
</head>
<body>

<h1>Canvas 仿 ECharts 金字塔图</h1>
<canvas id="pyramid" width="400" height="500"></canvas>

<script>
const canvas = document.getElementById('pyramid');
const ctx = canvas.getContext('2d');

const data = [
  {name: '第一层', value: 100},
  {name: '第二层', value: 80},
  {name: '第三层', value: 60},
  {name: '第四层', value: 40},
  {name: '第五层', value: 20}
];

const colors = ['#ff4d4f','#ff7a45','#ffa940','#ffd666','#73d13d'];

function drawPyramid(data){
  const canvasWidth = canvas.width;
  const canvasHeight = canvas.height;
  const totalValue = data[0].value; // 按最大值缩放
  const layerHeight = canvasHeight / data.length;

  ctx.clearRect(0,0,canvasWidth, canvasHeight);
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.font = '16px Arial';
  ctx.strokeStyle = '#fff';

  data.forEach((item, index) => {
    const layerWidth = canvasWidth * (item.value / totalValue);
    const x = (canvasWidth - layerWidth)/2;
    const y = index * layerHeight;

    // 绘制梯形
    const nextWidth = index < data.length - 1 ? canvasWidth * (data[index+1].value / totalValue) : 0;
    ctx.beginPath();
    ctx.moveTo(x, y);
    ctx.lineTo(x + layerWidth, y);
    ctx.lineTo(x + nextWidth + (layerWidth - nextWidth)/2, y + layerHeight);
    ctx.lineTo(x + (layerWidth - nextWidth)/2, y + layerHeight);
    ctx.closePath();
    ctx.fillStyle = colors[index % colors.length];
    ctx.fill();
    ctx.stroke();

    // 绘制文字
    ctx.fillStyle = '#000';
    ctx.fillText(`${item.name} (${item.value})`, canvasWidth/2, y + layerHeight/2);
  });
}

drawPyramid(data);
</script>

</body>
</html>


🔹 特性说明

  1. 自适应 Canvas
    • 金字塔图根据 Canvas 宽高自动绘制
    • 每层高度相等
  2. 按比例绘制
    • 每层宽度按数据值占最大值的比例
    • 实现金字塔逐层收窄效果
  3. 文字显示
    • 在每层中央显示层名和数值
  4. 颜色自定义
    • colors 数组可自由定义每层颜色

🔹 扩展思路

  • 鼠标悬浮提示:用 mousemove 监听坐标,显示浮动 tooltip
  • 百分比显示:在 fillText 中显示占比
  • 动画效果:使用 requestAnimationFrame 逐步绘制每层