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官网)

相关推荐
3Katrina几秒前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
前端_学习之路1 小时前
React--Fiber 架构
前端·react.js·架构
伍哥的传说1 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js
qq_424409191 小时前
uniapp的app项目,某个页面长时间无操作,返回首页
前端·vue.js·uni-app
我在北京coding1 小时前
element el-table渲染二维对象数组
前端·javascript·vue.js
布兰妮甜1 小时前
Vue+ElementUI聊天室开发指南
前端·javascript·vue.js·elementui
SevgiliD1 小时前
el-button传入icon用法可能会出现的问题
前端·javascript·vue.js
我在北京coding1 小时前
Element-Plus-全局自动引入图标组件,无需每次import
前端·javascript·vue.js
柚子8162 小时前
scroll-marker轮播组件不再难
前端·css
你的人类朋友2 小时前
🫏光速入门cURL
前端·后端·程序员