Antd Charts 组织架构图 && 指标拆解图

前言 复制代码
-   开箱即用:默认呈现高质量图表,将对开发体验及用户体验的研究沉淀入图表的默认配置项
-   易于配置:用户能够根据具体业务需要较为轻松的调整图表细节
-   体验良好:视觉和交互体验聚焦于如何能够**展示和发现信息**"这一图表本源的职能上

它的文档是真的少。。。。。需要自己花时间研究。。。。。。。
业务需求 复制代码
1.根据数据层级关系,以树级的形式展开
2.支持一键展开,一键收起;
3.根据自己的UI,个性化设计

...类似于下面这种需求

存在的问题

1.整个图表,根据你传输的数据进行渲染

2.每个节点的折叠与展开

3.每个节点的样式自定义问题

4.特定的一键展开与一键收起

下面我们一个个来解决

核心API简化

  • 节点无法收起与展开
对象的形式 复制代码
markerCfg:{
        show: true,
    },
逻辑判断 复制代码
markerCfg: (cfg) => {
      return {
        position: 'right',
        show: cfg.children?.length,
        style: (arg) => {
          return {
            stroke: arg.value.percent > 0.3 ? stroke : '#1f8fff',
          };
        },
      };
    },
  • 节点自定义---一般是避免不了!!!

支持单节点添加多内容,不止三个,通过group!.addShape('text', {...})

节点样式自定义 复制代码
customContent: (item, group, cfg) => {
    const { startX, startY, width } = cfg;
    const { text, value, icon } = item;
    let textShape, valueShape, iconShape; // 这里不止添加三个!!!
    
    textShape =
      text &&
      group!.addShape('text', {
        attrs: {
          textBaseline: 'top',
          x: startX,
          y: startY,
          text,
          fill: '#aaa',
        },
        // group 内唯一字段
        name: `text-${Math.random()}`,
      });
    valueShape =
      value &&
      group!.addShape('text', {
        attrs: {
          textBaseline: 'top',
          x: startX + width / 2,
          y: startY,
          text: value,
          fill: '#f00',
        },
        name: `value-${Math.random()}`,
      });
    iconShape =
      icon &&
      group!.addShape('image', {
        attrs: {
          x: startX,
          y: startY,
          width: 72,
          height: 72,
          img: icon,
        },
        name: `image-${Math.random()}`,
      });
    return Math.max(
      textShape?.getBBox().height ?? 0,
      valueShape?.getBBox().height ?? 0,
      iconShape?.getBBox().height ?? 0,
    );
  },
yaml 复制代码
##### 数据的转化

```后端数据格式
const fecth = {
    data:{
        id: '1',
        type: 0,
        count: 15,
        childList: [
            {},
            {},
            {}
        ]
        ....
    }
}
前端数据转换---最简单粗暴的递归 复制代码
 // 按照组件类库的数据格式
 // 下面以指标拆解图的格式为例
 const { data = {} } = await fetchData()
 const handleTransformData = ( arr = [] ) => {
    const finnallyData =  arr?.map(item=>({
        // 我们想要的数据格式· 其实递归 === 套公式
        // 结构出来最美观、方便了...
        id: item?.id,
        value: {
        title: item?.nodeName,
            items: [
                {
                    type: item?.type,
                    count: item?.count
                }
            ]
        },
        children: handleTransformData(item?.childList) || null, // 核心一步
    }))
    
    return finnallyData
 }
  • 节点的配置
js 复制代码
nodeCfg: {
      size: [140, 25],
      percent: {
        position: 'bottom',
        size: 4,
        style: (arg) => {
          return {
            radius: [0, 0, 0, 2],
            fill: arg.value.percent > 0.3 ? stroke : '#1f8fff',
          };
        },
      },
      items: {
        containerStyle: {
          fill: '#fff',
        },
        padding: 6,
        style: (cfg, group, type) => {
          const styles = {
            icon: {
              width: 12,
              height: 12,
            },
            value: {
              fill: '#f00',
            },
            text: {
              fill: '#aaa',
            },
          };
          return styles[type];
        },
      },
      nodeStateStyles: {
        hover: {
          lineWidth: 2,
        },
      },
      title: {
        containerStyle: {
          fill: 'transparent',
        },
        style: {
          fill: '#000',
          fontSize: 12,
        },
      },
      style: (arg) => {
        return {
          fill: '#fff',
          radius: 2,
          stroke: arg.value.percent > 0.3 ? stroke : '#1f8fff',
        };
      },
    },
  • 节点的起始点
  • 边的配置
js 复制代码
edgeCfg: {
      label: {
        style: {
          fill: '#aaa',
          fontSize: 12,
          fillOpacity: 1,
        },
      },
      style: (edge) => {
        return {
          stroke: '#518AD3',
          strokeOpacity: 0.5,
        };
      },
      endArrow: {
        fill: '#518AD3',
      },
      edgeStateStyles: {
        hover: {
          strokeOpacity: 1,
        },
      },
    },
  • 交互方式 根据意思:画布拖拽,节点拖拽,zoom-canvas我也不知道。。。
交互方式 复制代码
behaviors: ['drag-canvas', 'zoom-canvas', 'drag-node'],
  • 是否居中
js 复制代码
 fitCenter: true
  • 是否自适应
js 复制代码
 autoFit: true
  • 是否有动画
js 复制代码
 animate: false

数据的处理

  • 后端接口支持

  • 后端数据返回的形式,一级一级的返回,或者是数据一把搂回来

  • 当接口数据一把返回给我们,我们如何控制显示层级,坑点!!! 当如果采用的是组织架构图,那真是不好意思,人家类库还不支持控制层级,当然,你要相信Antd团队的创造力,多看文档不会让你失望。

指标拆解图的出现

看着样子确实差不多,但是里面可以配置的东西,可以说是完全不同!!!

通过文档案例以及API介绍

我们可以发现,指标拆解图支持异步加载控制层级显示,完美的解决我们的,一键展开、一键收起,支持单节点展开及异步加载数据功能

异步加载

js 复制代码
const fetchData = () => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(
          [1, 2].map(() => ({
            id: 'A2' + Math.random().toString(),
            value: {
              title: '异步节点' + Math.random().toString(),
              items: [
                {
                  text: '595万',
                },
                {
                  text: '占比',
                  value: '50%',
                  icon: 'https://gw.alipayobjects.com/zos/antfincdn/iFh9X011qd/7797962c-04b6-4d67-9143-e9d05f9778bf.png',
                },
              ],
            },
          })),
        );
      }, 1000);
    });
  };

  const getChildren = async () => {
    const asyncData = await fetchData();
    return asyncData;
  };
  
   const config = {
    data,
    autoFit: false,
    nodeCfg: {
      getChildren,
    },
    markerCfg: (cfg) => {
      return {
        show: true,
      };
    },
    behaviors: ['drag-canvas', 'zoom-canvas', 'drag-node'],
  };

控制层级显示

需求解决方案:

js 复制代码
1.后端接口一把把所有的数据返回,前端通过level控制显示层级 (完成一键展开)
2.当时,我通过条件渲染的方法,也就是写了两个图表,因为即使通过 useState() 声明一个状态,也不起作用,这个图表默认展示两层 (完成一键收起)
3.点击单节点展开,由于后端一把数据已经返回,只是通过level控制显示层级,此处无需异步加载,即可

坑点记录

  1. 数据无法set进去!!!记得检测id是否存在重复问题,当时我的后端就是,没有id给我设置为null,我又好巧不巧 id: item?.id || "1",设置节点ID默认值,排查一上午,才发现这个问题,我的内心是无比的崩溃的...
  2. 图表的tooltip,在示例上设置,能正常显示,结果本地看不到,我的内心也是十分的崩溃,一开始真的无从下手去排查,过了一会发现,它有时闪那么一下,脑子一闪,我好像设置是他的节点事件 node:mouseenter,来试验人家的方法,忘记删掉了,记得删除!记得删除!记得删除!,不然就等着崩溃,脑子宕机。。。
相关推荐
AAI机器之心18 小时前
LLM大模型:开源RAG框架汇总
人工智能·chatgpt·开源·大模型·llm·大语言模型·rag
杨荧18 小时前
【JAVA开源】基于Vue和SpringBoot的洗衣店订单管理系统
java·开发语言·vue.js·spring boot·spring cloud·开源
zqx_720 小时前
随记 前端框架React的初步认识
前端·react.js·前端框架
FIT2CLOUD飞致云1 天前
测试管理新增视图与高级搜索功能,测试计划支持一键生成缺陷详情,MeterSphere开源持续测试工具v3.3版本发布
开源·接口测试·metersphere·团队协作·持续测试·测试管理
杨荧1 天前
【JAVA开源】基于Vue和SpringBoot的旅游管理系统
java·vue.js·spring boot·spring cloud·开源·旅游
笑非不退1 天前
前端框架对比和选择
前端框架
杨荧2 天前
【JAVA开源】基于Vue和SpringBoot的水果购物网站
java·开发语言·vue.js·spring boot·spring cloud·开源
老章学编程i2 天前
Vue工程化开发
开发语言·前端·javascript·vue.js·前端框架
x-cmd2 天前
[241005] 14 款最佳免费开源图像处理库 | PostgreSQL 17 正式发布
数据库·图像处理·sql·安全·postgresql·开源·json
秃头女孩y2 天前
React基础-快速梳理
前端·react.js·前端框架