要約: この記事は元々、Grape City の技術チームによって CSDN に公開されたものです。転載元を明記してください:グレープシティ公式ウェブサイト、グレープシティは、開発者に力を与えるための専門的な開発ツール、ソリューション、サービスを開発者に提供します。
金融業界では、特定の計算結果をレビューするために監査レビューが必要になることがよくありますが、この計算結果は複数のセルに依存する可能性があり、複数レベルの依存関係が存在します。規模が大きく、正確性に疑問があり、基本的に袋小路であるため、レビュープロセス全体の可視化が差し迫っています。現在、純粋なフロントエンドテーブルと Echart を使用して監査レビュープロセスを可視化しています。
1. まず、フロントエンドテーブルまたは Excel の参照従属関係を理解しましょう。
1. セル B1 に数式 =SUM(A1) を設定します。セル A1 はセル B1 の参照セル (参照関係)です。
2. セル B1 に数式 =SUM(A1) を設定します。セルB1はセルA1の下位セルです(依存関係)
2. 次に、最終的な実現効果を見てみましょう。
1. 参照関係
2.所属
3. 今回は、Echarts のツリー図を使用して参照と所属を視覚化しています。Echarts を使い始めるには、Echarts の公式 Web サイトにアクセスして完全なチュートリアルを参照してください。多くの開発者によって作成された興味深い実用的なデモが多数あります。 Echarts コミュニティ。ここでは樹形図を使用します。
4. 次に、純粋なフロントエンド テーブル コントロールの API を使用して参照と所属関係を取得し、特定のセルの参照と所属関係を追跡し、根本的な問題を掘り起こし、「先祖の墓」を掘り下げ、これらの関係を Echarts ツリー図に構築します データ構造、ナンセンスなことを言わないでください、コア コードに直接進みます
// 递归构建追踪树
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;
}
5. 構築された参照と従属ツリーの 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、Excel レポートを 0 から自動化
スプレッドシートはショッピングカートとしても使える?3 つの簡単なステップで達成できます
純粋なフロントエンド Excel テーブル コントロール SpreadJS を使用して企業のキャッシュ フロー計算書を作成する