echarts 自定义形状-实现立体柱状图

一些复杂的图表样式,echarts 自带的 series 类型无法满足,可以使用 custom 类型,然后通过 canvas 手动绘制图表的形状。

1. 基础介绍

value() 函数

value() 函数官方说法是根据维度的名称或索引获取对应的数据值。 对于本示例来讲,
value(0) 用于获取 x 轴数据,value(1) 用于获取 y 轴数据。

coord() 函数

类型:coord([x, y])xy 分别是 x 轴的数据值以及 y 轴的数据值。可以通过 value() 来获取。coord() 函数的作用是根据 x 和 y 轴的数据值计算出坐标点

renderItem

当 series 的类型为 custom 时,通过 renderItem 函数提供图形渲染的逻辑。对于 data 中的每个数据项,都会调用一次 renderItem。函数格式:

arduino 复制代码
function renderItem(params, api) {
  // ...
  return {
    type: "group",
    // 形状列表
    children: [
      {
        // 已注册的形状名称
        type: "shapeName",
        // 形状参数,会被传递给 extendShape 函数
        shape: {},
        // 形状的样式,可以通过 api.style() 函数来获取基础样式
        style: api.style(),
        // 也可以覆盖某个样式属性,例如单独为每个形状设置不通的背景
        style: {
          ...api.style(),
          fill: "red", // 覆盖基础样式中的 fill
        }
      }
    ]
  }
}
扩展形状

在使用 renderItem 前,必须先使用 echarts.graphic.extendShape 函数来定义形状的样子。

javascript 复制代码
const shapeName = echarts.graphic.extendShape({
  buildPath(ctx, shape) {
    // ...
  }
})

ctx 可以获取到 canvas 的上下文,使用 canvas 来绘制形状。shape 是使用时传递的 shape 对象数据。参考[renderItem](# 自定义类型)的返回值。

注册形状

要想在 renderItem 中使用形状,需要先扩展形状,最后注册形状。

arduino 复制代码
echarts.graphic.registerShape('shapeName', shapeName);

第一个参数是形状的名称,在使用时直接指定的这个名称即可。

第二个参数是扩展形状的变量名称,例如[扩展形状](# 扩展形状)中的变量名 shapeName

立体柱状图解析

立体柱状图有三面:左侧面、右侧面、顶面,每一面对应一个形状,需要创建三个形状。

  • 顶部基础 y 轴:顶面每个点坐标的基础计算值。
  • 基础 x 轴: 左侧面和右侧面每个点坐标的基础计算值。
  • 斜角高度: 从中心点到两个侧面顶角的高度。
  • 中心点: coord([value(index, value)]) 计算后的坐标点。

坐标拆解

这些点需要在renderItem 中绘制。

2. 使用示例

css 复制代码
series: [
  {
    name: '示例',
    type: 'custom',
    renderItem: (params, api) => {
      const location = api.coord([api.value(0), api.value(1)]);
      // 返回一个图形元素
      return {
        type: 'InclinedRoofColumn',
        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: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: '#02FAFBFF' },
            { offset: 1, color: '#02FAFB00' }
          ])
        }
      };
    }
    data: []
  }
]
ini 复制代码
mounted() {
  // 绘制左侧面
  const InclinedRoofColumn = echarts.graphic.extendShape({
    buildPath: (ctx, shape) => {
      console.log('shape', shape);
      const xAxisPoint = shape.xAxisPoint;
      // 调整柱子形状主要代码
      const c0 = [shape.x + 15, shape.y];
      const c1 = [shape.x - 15, shape.y + 15];
      const c2 = [xAxisPoint[0] - 15, xAxisPoint[1]];
      const c3 = [xAxisPoint[0] + 15, xAxisPoint[1]];
      ctx.moveTo(c0[0], c0[1]).lineTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).closePath();
    }
  });
  
  // 注册形状 
  echarts.graphic.registerShape('InclinedRoofColumn', InclinedRoofColumn);
    this.$nextTick(() => {
      this.initChart(); // 初始化图表
  });
},

buildPath: (ctx, shape)

  • ctx: 获取 canvas 的上下文,可以理解为一个canvas中的绘制画笔,用来设置路径并且闭合路径。
  • shape: 通过自定义的 custom 传递,其中有一个xAxisPoint属性,可以设置左侧面和右侧面的填充高度(顶部不需要)
  • 填充高度:自定义的伪圆柱体里面的填充物需要有一个高度,具体填充多少根据自己的数据来知道。

绘制的四边形,其实就是四个顶点,只需要用 moveTo 来控制路径,然后在最后那个点进行闭合就行。偏移量是固定的值,可以根据需求去设置不同的值来改变形状。

上方示例中部分数据打印结果及路径分析:

3. 学习地址

blog.csdn.net/qq_35432583...
echarts.apache.org/zh/option.h... (echarts官网)

相关推荐
龙在天几秒前
Vue3 实现 B站 视差 动画
前端
KenXu2 分钟前
F2C Prompt to Design、AI 驱动的设计革命
前端
小鱼儿亮亮4 分钟前
canvas中画线条,线条效果比预期宽1像素且模糊问题分析及解决方案
前端·react.js
@大迁世界5 分钟前
用 popover=“hint“ 打造友好的 HTML 提示:一招让界面更“懂人”
开发语言·前端·javascript·css·html
伍哥的传说6 分钟前
Tailwind CSS v4 终极指南:体验 Rust 驱动的闪电般性能与现代化 CSS 工作流
前端·css·rust·tailwindcss·tailwind css v4·lightning css·utility-first
小鱼儿亮亮10 分钟前
使用Redux的combineReducers对数据拆分
前端·react.js
定栓16 分钟前
Typescript入门-类型断言讲解
前端·javascript·typescript
码间舞20 分钟前
你不知道的pnpm!如果我的电脑上安装了nvm,切换node版本后,那么pnpm还会共享一个磁盘的npm包吗?
前端·代码规范·前端工程化
用户15129054522023 分钟前
itoa函数
前端
xiaominlaopodaren24 分钟前
“UI里就可以请求数据库”,让你陌生的 React 特性
前端·javascript·react.js