最新技术资源(建议收藏)

https://www.grapecity.com.cn/resources/

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

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

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

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

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

1.引用关系

2.从属关系

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

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

// 递归构建追踪树
buildNodeTreeAndPaint = (spreadSource, trackCellInfo) => {
let info = this.getCellInfo(trackCellInfo);
let sheetSource = spreadSource.getSheetFromName(info.sheetName);
// 创建跟节点
let rootNode = this.creatNode(info.row, info.col, sheetSource, 0, ""); let name = rootNode.sheetName + "*" + rootNode.row + "*" + rootNode.col + "*" + Math.random().toString();
let precedentsRootNode = '';
let dependentsRootNode = '';
if (this.state.trackType === "Precedents" || this.state.trackType === "Both") {
this.getNodeChild(rootNode, sheetSource, "Precedents")
debugger;
console.log(rootNode)
if (this.state.trackType === "Both") {
let rootNodeChildren = JSON.parse(JSON.stringify(rootNode.children));
rootNode.children = [];
precedentsRootNode = JSON.parse(JSON.stringify(rootNode));
precedentsRootNode.children.push({
name: "Precedents",
value: "Precedents",
children: rootNodeChildren
})
this.setState({
precedentsRootNode: JSON.parse(JSON.stringify(precedentsRootNode)),
})
}
}
if (this.state.trackType === "Dependents" || this.state.trackType === "Both") {
this.getNodeChild(rootNode, sheetSource, "Dependents")
console.log(rootNode)
if (this.state.trackType === "Both") {
let deepInfo = [1];
let rootNodeChildren = JSON.parse(JSON.stringify(rootNode.children));
rootNode.children = [];
dependentsRootNode = JSON.parse(JSON.stringify(rootNode));
dependentsRootNode.children.push({
name: "Dependents",
value: "Dependents",
children: rootNodeChildren
})
this.setState({
dependentsRootNode: JSON.parse(JSON.stringify(dependentsRootNode)),
})
} }
if (this.state.trackType === "Both") {
precedentsRootNode.children = precedentsRootNode.children.concat(dependentsRootNode.children);
// let bothRootNode = precedentsRootNode.children[0].children.concat(dependentsRootNode.children[0].children)
this.setState({
rootNode1: JSON.parse(JSON.stringify(precedentsRootNode)),
})
} else {
this.setState({
rootNode1: JSON.parse(JSON.stringify(rootNode)),
})
}
}
creatNode = (row, col, sheet, deep, trackType) => {
let node = {
value: sheet.getValue(row, col),
position: sheet.name() + "!" + GC.Spread.Sheets.CalcEngine.rangeToFormula(new GC.Spread.Sheets.Range(row, col, 1, 1)),
deep: deep,
name: `${sheet.name()}!${GC.Spread.Sheets.CalcEngine.rangeToFormula(new GC.Spread.Sheets.Range(row, col, 1, 1))}\nvalue:${sheet.getValue(row, col)}`,
sheetName: sheet.name(),
row: row,
col: col,
trackType: trackType
};
return node;
}
getNodeChild = (rootNode, sheet, trackType) => {
let childNodeArray = [];
let children = [];
let row = rootNode.row, col = rootNode.col, deep = rootNode.deep;
if (trackType == "Precedents") {
children = sheet.getPrecedents(row, col);
}
else {
children = sheet.getDependents(row, col);
}
// let self = this;
if (children.length >= 1) {
children.forEach((node) => {
let row = node.row,
col = node.col,
rowCount = node.rowCount,
colCount = node.colCount,
_sheet = sheet.parent.getSheetFromName(node.sheetName);
if (rowCount > 1 || colCount > 1) {
for (let r = row; r < row + rowCount; r++) {
for (let c = col; c < col + colCount; c++) {
let newNode = this.creatNode(r, c, _sheet, deep + 1, trackType)
// if (deep < self.maxDeep) {
this.getNodeChild(newNode, _sheet, trackType);
// }
childNodeArray.push(newNode);
}
}
} else {
let newNode = this.creatNode(row, col, _sheet, deep + 1, trackType)
// if (deep < self.maxDeep) {
this.getNodeChild(newNode, _sheet, trackType);
// }
childNodeArray.push(newNode);
}
});
}
rootNode.children = childNodeArray;
}

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

myChart.setOption(
(option = {
tooltip: {
trigger: 'item',
triggerOn: 'mousemove'
},
series: [
{
type: 'tree',
data: [this.state.rootNode1],
top: '1%',
left: '15%',
bottom: '1%',
right: '7%',
symbolSize: 10,
orient: this.state.trackType === 'review'?'LR':'RL',
label: {
position: this.state.trackType === 'review'?'left':'right',
verticalAlign: 'middle',
align: this.state.trackType === 'review'?'right':'left',
},
leaves: {
label: {
position: this.state.trackType === 'review'?'right':'left',
verticalAlign: 'middle',
align: this.state.trackType === 'review'?'left':'right'
}
},
emphasis: {
focus: 'descendant'
},
// layout: 'radial',
expandAndCollapse: true,
animationDuration: 550,
animationDurationUpdate: 750
}
]
})
); option && myChart.setOption(option);

以上就是实现报表中公式引用从属关系Echarts可视化的核心实现逻辑,由于工程较大,如需获取源码,可私信获取。

拓展阅读

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

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

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

妙趣横生:利用Echarts实现SpreadJS引用从属关系的可视化魅力的更多相关文章

  1. 用Echarts实现SpreadJS引用从属关系可视化

    在金融行业,我们经常会有审计审查的需求,对某个计算结果进行审查,但是这个计算结果可能依赖多个单元格,而且会有会有多级依赖的情况,如果让我们的从业人员靠眼睛找,工作量巨大,而且准确性存疑,基本上死路一条 ...

  2. 利用echarts展示旅行足迹

    前言 一直有个环游世界的梦,周游列国,体验不同国家的人类文明,寻山访水,体验造物主大自然的伟大造化.毕竟人生不止眼前的苟且,还有诗和远方.这么多年以来,陆续走过了一些地方,每到一个地方,都让我离梦想又 ...

  3. 利用Echarts设计一个图表平台(一)

    Echarts是一款百度的开源图表库,里面提供了非常多的图表样式,我们今天要讲的内容是利用这一款开源js图表,制作一个能够动态定制的图表平台. 1)Echarts API介绍 首先我们先来看一下Ech ...

  4. echarts地图的引用

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

  5. echarts词云引用

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

  6. 利用ECharts开发的步骤

    引入Echarts的相关库文件,以及自定义的js文件 <script src="${pageContext.request.contextPath}/js/echarts/source ...

  7. 利用echarts自定义环形图

    一.代码 app.title = '通讯盒各版本用户占比'; option = { backgroundColor: '#0f0f31', title: { show:true, x:"le ...

  8. 利用echarts做图表统计

    以项目中的扇形统计图为例: 首先,第一步: 引入外部echarts.js文件 其次,第二步: HTML代码块 <div class="count-body-con count-tj&q ...

  9. 利用Echarts实现全国各个省份数据占比,图形为中国地图

    最近项目需求,需要一个对于全国各个省份的数据分析,图形最好是地图的样子,这样子更为直观. 最先想到的图表插件是Echarts,他的文档相对于阿里的G2,G6更加清晰一些.在Echarts 里找到的个 ...

  10. 利用echarts highcharts 实现自定义地图 关系图效果 侧边3D柱形图饼图散点图

    github 地址:  https://https://github.com/Gengshaoxuan/medataMap github 地址:  https://https://github.com ...

随机推荐

  1. C 语言编程 — 高级数据类型 — 字符串

    目录 文章目录 目录 前文列表 字符串 前文列表 <程序编译流程与 GCC 编译器> <C 语言编程 - 基本语法> <C 语言编程 - 基本数据类型> <C ...

  2. 未能加载文件或程序集“UFIDA.U8.UAP.GcRegister, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项

    这是做采购入库单新增的时候遇到的问题,我是采用模仿写用友u8的zpurrkdhead 主表视图和子表视图zpurrkdtail 去构建 xml文档这样做的,但是再做的时候 [cgcroutecode] ...

  3. [COCI2008-2009 #2] PERKET

    传送锚点:https://www.luogu.com.cn/problem/P2036 题目描述 Perket 是一种流行的美食.为了做好 Perket,厨师必须谨慎选择食材,以在保持传统风味的同时尽 ...

  4. C#中位枚举(Flags)

    在日常的开发工作当中,位枚举可能会被经常使用,如星期多选.租期多选等等,我们可以将多选字段做或运算,然后保存到数据库表的字段中,如 1 | 2 = 3(0001 | 0010 = 0011 = 3). ...

  5. 挨个配置资源组太麻烦?ROS伪参数一步搞定!

    介绍 伪参数 伪参数是资源编排服务ROS的编排引擎提供的固定参数,即在编写模板时可以使用的一系列预定义的参数,它们为模板提供了资源部署过程中的环境和执行上下文信息. 更多伪参数介绍请查看:ROS伪参数 ...

  6. Geatpy学习笔记1:官方案例

    一.入门 1.求解器模式入门 案例 1 import geatpy as ea import numpy as np # 构建问题 r = 1 # 目标函数需要用到的额外数据 @ea.Problem. ...

  7. redis安装和基础使用

    redis安装 mkdir /server/tools -p cd /server/tools echo 'PATH=/usr/local/redis/src:$PATH' >>/etc/ ...

  8. Yii 实现数据库SUM操作

    方法一:这种方法有个坑儿,就是as 后面的别名,必须是属性范围内的名字. $criteria = new CDbCriteria(); $criteria->select = 'sum(amou ...

  9. 算法金 | 再见,PCA 主成分分析!

    ​大侠幸会,在下全网同名[算法金] 0 基础转 AI 上岸,多个算法赛 Top [日更万日,让更多人享受智能乐趣] 1. 概念:数据降维的数学方法 定义 主成分分析(PCA)是一种统计方法,通过正交变 ...

  10. Java BigInteger类和BigDecimal()类

    BigInteger类 BigInteger 支持任意精度的整数,可以准确的表达任何大小的整数而不丢失精准度 BigInteger 位于 java.math包中 BigInteger()括号里必须是字 ...