3D柱状图

描述:当前是关于Echarts图表中的 示例。
 
            const xData = ['三幼', '四幼', '五幼', '二幼', '一幼']
const yData = [1000, 900, 800, 755, 600]
const title = '步数'
const unit = '步'

// 注册 3 个面图形: 前面 右面 上面
// c0:左下角,c1:右下角,c2:右上角,c3:左上角
// 绘制前面
const CubeFront_1 = echarts.graphic.extendShape({
  shape: {
    x: 0,
    y: 0
  },
  buildPath: function(ctx, shape) {
    // 会canvas的应该都能看得懂,shape是从custom传入的
    // console.log(shape)
    const xAxisPoint = shape.xAxisPoint
    const offset = [40, 40]
    const c0 = [shape.x - offset[0], shape.y]
    const c1 = [shape.x + offset[1], shape.y]
    const c2 = [xAxisPoint[0] + offset[1], xAxisPoint[1]]
    const c3 = [xAxisPoint[0] - offset[0], xAxisPoint[1]]
    ctx.moveTo(c0[0], c0[1])
      .lineTo(c1[0], c1[1])
      .lineTo(c2[0], c2[1])
      .lineTo(c3[0], c3[1])
      .closePath()
  }
})
// 绘制右面
const CubeRight_1 = echarts.graphic.extendShape({
  shape: {
    x: 0,
    y: 0
  },
  buildPath: function(ctx, shape) {
    // 会canvas的应该都能看得懂,shape是从custom传入的
    const xAxisPoint = shape.xAxisPoint
    const c0 = [shape.x + 40, shape.y]
    const c1 = [shape.x + 60, shape.y - 16]
    const c2 = [xAxisPoint[0] + 60, xAxisPoint[1] - 16]
    const c3 = [xAxisPoint[0] + 40, xAxisPoint[1]]
    ctx.moveTo(c0[0], c0[1])
      .lineTo(c1[0], c1[1])
      .lineTo(c2[0], c2[1])
      .lineTo(c3[0], c3[1])
      .closePath()
  }
})
// 绘制上面
const CubeTop_1 = echarts.graphic.extendShape({
  shape: {
    x: 0,
    y: 0
  },
  buildPath: function(ctx, shape) {
    // 会canvas的应该都能看得懂,shape是从custom传入的

    const c0 = [shape.x - 40, shape.y]
    const c1 = [shape.x + 40, shape.y]
    const c2 = [shape.x + 60, shape.y - 16]
    const c3 = [shape.x - 20, shape.y - 16]
    ctx.moveTo(c0[0], c0[1])
      .lineTo(c1[0], c1[1])
      .lineTo(c2[0], c2[1])
      .lineTo(c3[0], c3[1])
      .closePath()
  }
})

/**
 * 各个面的颜色
 */
const CubeColors = [
  {
    // 前
    front: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
      offset: 0,
      color: 'rgba(45,193,178,1)'
    },
    {
      offset: 1,
      color: 'rgba(191,237,232,1)'
    }
    ]),
    // 右
    right: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
      offset: 0,
      color: 'rgba(23,148,135,1)'
    },
    {
      offset: 1,
      color: 'rgba(138,219,211,1)'
    }
    ]),
    // 上
    top: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
      offset: 0,
      color: 'rgba(100,231,218,1)'
    },
    {
      offset: 1,
      color: 'rgba(177,244,237,1)'
    }
    ])
  }
];

// 注册
registerShape();

option = {
   grid: {
      top: '20%'
   },
   tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' }
   },
   xAxis: [
      {
      type: 'category',
      data: xData || [],
      axisTick: false, 
      axisLine: {
         lineStyle: {
            color: '#EDF2F7'
         }
      },
      axisLabel: {
         fontSize: 14,
         color: '#18191B'
      }
      }
   ],
   yAxis: [
      {
         name: `${title}(${unit})`,
         type: 'value',
         max: 1200,
         axisLine: {
            show: false 
         },
         splitLine: {
            show: false
         },
         axisLabel: {
            fontSize: 14,
            color: '#18191B'
         }
      }
   ],

   series: [
      {
      name: title,
      type: 'custom',
      renderItem: (params, api) => {
         return renderItem(params, api)
      },
      data: yData || []
      }
   ]
};

/**
 * 注册图形
 */
function registerShape() {
   echarts.graphic.registerShape('cubeFront', CubeFront_1)
   echarts.graphic.registerShape('cubeRight', CubeRight_1)
   echarts.graphic.registerShape('cubeTop', CubeTop_1)
}
/**
 * 渲染图形
 * @description 参考链接 https://echarts.apache.org/zh/option.html#series-custom.renderItem
 * @param params 包含了当前数据信息和坐标系的信息
 * @param api 开发者可调用的方法集合
*/
function renderItem(params, api) {
   const location = api.coord([api.value(0), api.value(1)])
   const fillColor = CubeColors[0]

   // 获取当前数据的索引
   const { dataIndex } = params
   // 这里可以根据当前数据的索引 来获取对应的图片
   const imageArr = [
      '//img.isqqw.com/profile/upload/2024/07/10/13c1cd81-4cc0-4308-9b11-18579cd4e699.png',
      '//img.isqqw.com/profile/upload/2024/07/10/a8bed5c7-b9e1-457d-b664-4426d2e91d65.png',
      '//img.isqqw.com/profile/upload/2024/07/10/731df015-15e5-42e4-9719-be1d66cb933f.png',
      '//img.isqqw.com/profile/upload/2024/07/10/b22dd0c5-cea4-4e22-b970-f28838d72785.png',
      '//img.isqqw.com/profile/upload/2024/07/10/be73337b-038f-4fb1-b17e-1604a628d19e.png'
   ];
   const imageURL = imageArr[dataIndex]
   return {
      type: 'group',
      children: [
         {
         type: 'cubeFront',
         shape: {
            api,
            xValue: api.value(0),
            yValue: api.value(1),
            x: location[0],
            y: location[1],
            xAxisPoint: api.coord([api.value(0), 0])
         },
         style: {
            fill: fillColor.front
         }
         },
         {
         type: 'cubeRight',
         shape: {
            api,
            xValue: api.value(0),
            yValue: api.value(1),
            x: location[0],
            y: location[1],
            xAxisPoint: api.coord([api.value(0), 0])
         },
         style: {
            fill: fillColor.right
         }
         },
         {
         type: 'cubeTop',
         shape: {
            api,
            xValue: api.value(0),
            yValue: api.value(1),
            x: location[0],
            y: location[1],
            xAxisPoint: api.coord([api.value(0), 0])
         },
         style: {
            fill: fillColor.top
         }
         }, 
         {
         type: 'image',
            // 图片的位置 图片大小是 60*70
            x: location[0] - 20,
            y: location[1] - 95,
            style: {
               image: imageURL
            },
            z: 2
         }
      ]
   }
}