在金融行业,我们经常会有审计审查的需求,对某个计算结果进行审查,但是这个计算结果可能依赖多个单元格,而且会有会有多级依赖的情况,如果让我们的从业人员靠眼睛找,工作量巨大,而且准确性存疑,基本上死路一条,因此让整个审查过程可视化,迫在眉睫,现在我们利用纯前端表格和Echarts将审计审查过程可视化

一.首先我们先了解一下前端表格或Excel中引用和从属关系:

1.在单元格B1中设置公式 =SUM(A1)。 单元格A1是单元格B1的引用单元格(引用关系

2.在单元格B1中设置公式 =SUM(A1)。 单元格B1是单元格A1的从属单元格(从属关系

二.接下来我们看一下最终实现效果:

1.引用关系

2.从属关系

三.本次我们用的是Echarts的树图将引用和从属关系可视化,关于Echarts上手,大家去Echarts官网有完整上手教程,Echarts社区有很多开发者做的许多有趣又实用的demo,这里我们用的是树图

四.接下来我们要用纯前端表格控件的获取引用和从属关系的api将某个单元格的引用和从属关系顺藤摸瓜,刨根问题,刨到“祖坟”上,将这些关系,构造成Echarts树图的data结构,废话不说,直接上核心代码

  1. // 递归构建追踪树
  2. buildNodeTreeAndPaint = (spreadSource, trackCellInfo) => {
  3. let info = this.getCellInfo(trackCellInfo);
  4. let sheetSource = spreadSource.getSheetFromName(info.sheetName);
  5. // 创建跟节点
  6. let rootNode = this.creatNode(info.row, info.col, sheetSource, 0, "");
  7. let name = rootNode.sheetName + "*" + rootNode.row + "*" + rootNode.col + "*" + Math.random().toString();
  8. let precedentsRootNode = '';
  9. let dependentsRootNode = '';
  10. if (this.state.trackType === "Precedents" || this.state.trackType === "Both") {
  11. this.getNodeChild(rootNode, sheetSource, "Precedents")
  12. debugger;
  13. console.log(rootNode)
  14. if (this.state.trackType === "Both") {
  15. let rootNodeChildren = JSON.parse(JSON.stringify(rootNode.children));
  16. rootNode.children = [];
  17. precedentsRootNode = JSON.parse(JSON.stringify(rootNode));
  18. precedentsRootNode.children.push({
  19. name: "Precedents",
  20. value: "Precedents",
  21. children: rootNodeChildren
  22. })
  23. this.setState({
  24. precedentsRootNode: JSON.parse(JSON.stringify(precedentsRootNode)),
  25. })
  26. }
  27. }
  28. if (this.state.trackType === "Dependents" || this.state.trackType === "Both") {
  29. this.getNodeChild(rootNode, sheetSource, "Dependents")
  30. console.log(rootNode)
  31. if (this.state.trackType === "Both") {
  32. let deepInfo = [1];
  33. let rootNodeChildren = JSON.parse(JSON.stringify(rootNode.children));
  34. rootNode.children = [];
  35. dependentsRootNode = JSON.parse(JSON.stringify(rootNode));
  36. dependentsRootNode.children.push({
  37. name: "Dependents",
  38. value: "Dependents",
  39. children: rootNodeChildren
  40. })
  41. this.setState({
  42. dependentsRootNode: JSON.parse(JSON.stringify(dependentsRootNode)),
  43. })
  44. }
  45. }
  46. if (this.state.trackType === "Both") {
  47. precedentsRootNode.children = precedentsRootNode.children.concat(dependentsRootNode.children);
  48. // let bothRootNode = precedentsRootNode.children[0].children.concat(dependentsRootNode.children[0].children)
  49. this.setState({
  50. rootNode1: JSON.parse(JSON.stringify(precedentsRootNode)),
  51. })
  52. } else {
  53. this.setState({
  54. rootNode1: JSON.parse(JSON.stringify(rootNode)),
  55. })
  56. }
  57. }
  58. creatNode = (row, col, sheet, deep, trackType) => {
  59. let node = {
  60. value: sheet.getValue(row, col),
  61. position: sheet.name() + "!" + GC.Spread.Sheets.CalcEngine.rangeToFormula(new GC.Spread.Sheets.Range(row, col, 1, 1)),
  62. deep: deep,
  63. name: `${sheet.name()}!${GC.Spread.Sheets.CalcEngine.rangeToFormula(new GC.Spread.Sheets.Range(row, col, 1, 1))}\nvalue:${sheet.getValue(row, col)}`,
  64. sheetName: sheet.name(),
  65. row: row,
  66. col: col,
  67. trackType: trackType
  68. };
  69. return node;
  70. }
  71. getNodeChild = (rootNode, sheet, trackType) => {
  72. let childNodeArray = [];
  73. let children = [];
  74. let row = rootNode.row, col = rootNode.col, deep = rootNode.deep;
  75. if (trackType == "Precedents") {
  76. children = sheet.getPrecedents(row, col);
  77. }
  78. else {
  79. children = sheet.getDependents(row, col);
  80. }
  81. // let self = this;
  82. if (children.length >= 1) {
  83. children.forEach((node) => {
  84. let row = node.row,
  85. col = node.col,
  86. rowCount = node.rowCount,
  87. colCount = node.colCount,
  88. _sheet = sheet.parent.getSheetFromName(node.sheetName);
  89. if (rowCount > 1 || colCount > 1) {
  90. for (let r = row; r < row + rowCount; r++) {
  91. for (let c = col; c < col + colCount; c++) {
  92. let newNode = this.creatNode(r, c, _sheet, deep + 1, trackType)
  93. // if (deep < self.maxDeep) {
  94. this.getNodeChild(newNode, _sheet, trackType);
  95. // }
  96. childNodeArray.push(newNode);
  97. }
  98. }
  99. } else {
  100. let newNode = this.creatNode(row, col, _sheet, deep + 1, trackType)
  101. // if (deep < self.maxDeep) {
  102. this.getNodeChild(newNode, _sheet, trackType);
  103. // }
  104. childNodeArray.push(newNode);
  105. }
  106. });
  107. }
  108. rootNode.children = childNodeArray;
  109. }

五.将构造好的引用和从属树rootNode在Echarts中渲染

  1. myChart.setOption(
  2. (option = {
  3. tooltip: {
  4. trigger: 'item',
  5. triggerOn: 'mousemove'
  6. },
  7. series: [
  8. {
  9. type: 'tree',
  10. data: [this.state.rootNode1],
  11. top: '1%',
  12. left: '15%',
  13. bottom: '1%',
  14. right: '7%',
  15. symbolSize: 10,
  16. orient: this.state.trackType === 'review'?'LR':'RL',
  17. label: {
  18. position: this.state.trackType === 'review'?'left':'right',
  19. verticalAlign: 'middle',
  20. align: this.state.trackType === 'review'?'right':'left',
  21. },
  22. leaves: {
  23. label: {
  24. position: this.state.trackType === 'review'?'right':'left',
  25. verticalAlign: 'middle',
  26. align: this.state.trackType === 'review'?'left':'right'
  27. }
  28. },
  29. emphasis: {
  30. focus: 'descendant'
  31. },
  32. // layout: 'radial',
  33. expandAndCollapse: true,
  34. animationDuration: 550,
  35. animationDurationUpdate: 750
  36. }
  37. ]
  38. })
  39. );
  40. option && myChart.setOption(option);

以上就是实现报表中公式引用从属关系Echarts可视化的核心实现逻辑,由于工程较大,需要完整内容可以留言。。

拓展阅读

React + Springboot + Quartz,从0实现Excel报表自动化

电子表格也能做购物车?简单三步就能实现

使用纯前端类Excel表格控件SpreadJS构建企业现金流量表

用Echarts实现SpreadJS引用从属关系可视化的更多相关文章

  1. 用Echarts的力向导图可视化数据

    学习背景:做一个图论的题目的时候需要将结果可视化来直观的看效果,所以使用Echarts来画.感觉效果不错. Echarts下载地址:https://echarts.baidu.com/download ...

  2. echarts地图的引用

    最近是跟echarts杠上了 所在公司是搞数据的 所以身为前端的我 就必须使用echarts将数据展示出来 ,进公司一周 ,前前后后大概用了八九种echarts图,我举得最难的就是引用的地图,因为刚开 ...

  3. echarts词云引用

    最近项目中需要使用echarts的词云图,因为几经波折才引用成功,所以想记下来跟大家分享,(我的随笔不会写那么多让人需要动脑子去理解的东西,就是记录一下步骤,因为经验甚少,底层原理懂得不多,所以就先记 ...

  4. echarts 移动端地图数据可视化教程

    如上效果图: 以下未代码: <!doctype html> <html lang="en">   <head> <meta charset ...

  5. echarts 移动端地图数据可视化开发教程

    如上效果图: 以下未代码: <!doctype html> <html lang="en">   <head> <meta charset ...

  6. Echarts数据可视化,easyshu图表集成。

      介绍: ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Sa ...

  7. 项目实战:在线报价采购系统(React +SpreadJS+Echarts)

    小伙伴们对采购系统肯定不陌生,小到出差路费.部门物资采购:大到生产计划.原料成本预估都会涉及到该系统. 管理人员可以通过采购系统减少管理成本,说是管理利器毫不过分,对于采购的效率提升也有极大帮助. 但 ...

  8. 【可视化】DataV接入ECharts图表库 可视化利器强强联手

    DataV接入ECharts图表库 可视化利器强强联手 摘要: 两个扛把子级产品的结合,而且文末有彩蛋. DataV 数据可视化是搭建每年天猫双十一作战大屏的幕后功臣,ECharts 是广受数据可视化 ...

  9. 【教程】高德地图使用ECharts实现数据可视化

    关于百度地图结合ECharts实现数据可视化的资料已经很多了,毕竟是官方提供支持的,这里就不再赘述.今天我们来讲一下让高德地图与ECharts结合来实现数据可视化图表的展示. 一.ECharts 高德 ...

  10. python+echarts+flask实现对全国疫情数据的爬取并可视化展示

    用Python进行数据爬取并存储到数据库,3.15学习总结(Python爬取网站数据并存入数据库) - 天岁 - 博客园 (cnblogs.com) 通过echarts+flask实现数据的可视化展示 ...

随机推荐

  1. Vue3 Vite3 多环境配置 - 基于 vite 创建 vue3 全家桶项目(续篇)

    在项目或产品的迭代过程中,通常会有多套环境,常见的有: dev:开发环境 sit:集成测试环境 uat:用户接收测试环境 pre:预生产环境 prod:生产环境 环境之间配置可能存在差异,如接口地址. ...

  2. 关于docker创建容器报错-docker: Error response from daemon: runtime "io.containerd.runc.v2" binary not installed

    今天在对一台服务器(docker相关的业务服务器)进行OS补丁时,默认使用的 yum update -y 对所有的安装包进行了升级 升级完成后,让应用方检查确认应用及功能是否一切正常,如果不正常,严重 ...

  3. 从 C# 崩溃异常 中研究页堆布局

    一:背景 1.讲故事 最近遇到一位朋友的程序崩溃,发现崩溃点在富编辑器 msftedit 上,这个不是重点,重点在于发现他已经开启了 页堆 ,看样子是做了最后的挣扎. 0:000> !analy ...

  4. .Net CLR GC plan_phase二叉树和Brick_table

    楔子 别那么懒,勤快点.以下取自CLR PreView 7.0. 主题 GC计划阶段(plan_phase)主要就两个部分,一个是堆里面的对象构建一颗二叉树(这颗二叉树的每个节点包含了诸如对象移动信息 ...

  5. Java注解(2):实现自己的ORM

    搞过Java的码农都知道,在J2EE开发中一个(确切地说,应该是一类)很重要的框架,那就是ORM(Object Relational Mapping,对象关系映射).它把Java中的类和数据库中的表关 ...

  6. [Err] 1052 - Column ‘roleId‘ in where clause is ambiguous

    1.先看错误的sql语句: select a.authName from roles as r,authority as a,role_ah as ra where ra.roleId=r.roleI ...

  7. 【JavaWeb】学习笔记——JSP

    概念 全称:Java Server Pages, Java服务端页面 描述:一种动态的网页技术,可以在其中定义HTML.JS.CSS等静态内容,以及Java代码的动态内容 说明:JSP = HTML ...

  8. JDK8下载安装及环境配置

    Java基础知识 Java的三种版本 JavaSE :标准版,主要用于开发桌面程序,控制台开发等等 JavaME:嵌入式开发,主要用于开发手机,小家电等等,目前使用的比较少 JavaEE:企业级开发, ...

  9. 远程桌面报错credssp

    远程桌面连接的时候有时出现"出现身份验证错误.要求的函数不受支持:这可能是由于CredSSP 加密 Oracle 修正"的提示, 针对这种情况有以下两种版本的操作系统解决方案: w ...

  10. 【云原生 · Kubernetes】部署高可用 kube-controller-manager 集群

    个人名片: 因为云计算成为了监控工程师‍ 个人博客:念舒_C.ying CSDN主页️:念舒_C.ying 部署高可用 kube-controller-manager 集群 12.1 创建 kube- ...