在Web页面使用d3-graphviz绘制函数调用关系图

1、d3-graphviz绘制函数调用关系图

这个网页实现了以下功能:

  1. 使用D3-graphviz绘制函数调用关系图
  2. 支持图表缩放和自适应
  3. 提供了更新图表的按钮
  4. 使用DOT语言定义图形结构
  5. 节点使用不同的颜色和形状进行区分

主要特点:

  • 图表可以通过鼠标滚轮进行缩放
  • 可以拖动图表以查看不同部分
  • 节点使用填充色区分不同类型的函数
  • 箭头清晰地显示了函数之间的调用关系
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Function Call Graph</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/viz.js/2.1.2/viz.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3-graphviz/5.1.0/d3-graphviz.min.js"></script>
    <style>
        #graph {
            width: 100%;
            height: 600px;
            border: 1px solid #ccc;
            margin: 20px 0;
        }
        .controls {
            margin: 20px;
        }
        button {
            padding: 8px 16px;
            margin-right: 10px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div class="controls">
        <button onclick="updateGraph()">更新图表</button>
    </div>
    <div id="graph"></div>

    <script>
        // 示例函数调用数据
        const defaultData = `
            digraph {
                node [style="filled" fillcolor="#f0f8ff"]
                
                main -> parseData
                main -> processData
                main -> renderUI
                parseData -> validateInput
                parseData -> formatData
                processData -> calculateMetrics
                processData -> filterResults
                renderUI -> createLayout
                renderUI -> updateView
                createLayout -> setupComponents
                updateView -> refreshData
                
                // 设置节点样式
                main [fillcolor="#e6f3ff" shape="box"]
                parseData [fillcolor="#f0f8ff"]
                processData [fillcolor="#f0f8ff"]
                renderUI [fillcolor="#f0f8ff"]
            }
        `;

        // 初始化图表
        const graphviz = d3.select("#graph")
            .graphviz()
            .zoom(true)
            .fit(true);

        // 渲染初始图表
        graphviz.renderDot(defaultData);

        // 更新图表的函数
        function updateGraph() {
            // 这里可以添加新的数据或修改现有数据
            const newData = `
                digraph {
                    node [style="filled" fillcolor="#f0f8ff"]
                    
                    main -> parseData
                    main -> processData
                    main -> renderUI
                    parseData -> validateInput
                    parseData -> formatData
                    processData -> calculateMetrics
                    processData -> filterResults
                    renderUI -> createLayout
                    renderUI -> updateView
                    createLayout -> setupComponents
                    updateView -> refreshData
                    
                    // 添加新的节点和连接
                    calculateMetrics -> analyzeData
                    analyzeData -> generateReport
                    
                    main [fillcolor="#e6f3ff" shape="box"]
                    parseData [fillcolor="#f0f8ff"]
                    processData [fillcolor="#f0f8ff"]
                    renderUI [fillcolor="#f0f8ff"]
                    analyzeData [fillcolor="#e6f3ff"]
                    generateReport [fillcolor="#e6f3ff"]
                }
            `;
            
            graphviz
                .renderDot(newData);
        }
    </script>
</body>
</html>

2、dot渲染成矩形节点形状大小调整

  1. 节点样式改为矩形:

    • 使用 shape="rect" 设置矩形形状
    • 通过 width=1.5height=0.5 控制节点大小
  2. 布局调整:

    • 设置图表容器宽度为 800px
    • 添加 nodesep=0.3 控制节点间距
    • 添加 ranksep=0.4 控制层级间距
  3. 其他优化:

    • 减小箭头大小 arrowsize=0.8
    • 调整字体大小 fontsize=12
    • 使图表在页面中居中显示
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Function Call Graph</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/viz.js/2.1.2/viz.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3-graphviz/5.1.0/d3-graphviz.min.js"></script>
    <style>
        #graph {
            width: 800px;
            height: 600px;
            border: 1px solid #ccc;
            margin: 20px auto;
        }
        .controls {
            width: 800px;
            margin: 20px auto;
        }
        button {
            padding: 8px 16px;
            margin-right: 10px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div class="controls">
        <button onclick="updateGraph()">更新图表</button>
    </div>
    <div id="graph"></div>

    <script>
        const defaultData = `
            digraph {
                // 设置全局节点样式为矩形
                node [
                    shape="rect"
                    style="filled"
                    fillcolor="#f0f8ff"
                    width=1.5
                    height=0.5
                    fontsize=12
                ]
                
                // 设置图形布局方向和间距
                graph [
                    rankdir="TB"
                    nodesep=0.3
                    ranksep=0.4
                ]
                
                // 设置边的样式
                edge [
                    arrowsize=0.8
                ]
                
                main -> parseData
                main -> processData
                main -> renderUI
                parseData -> validateInput
                parseData -> formatData
                processData -> calculateMetrics
                processData -> filterResults
                renderUI -> createLayout
                renderUI -> updateView
                createLayout -> setupComponents
                updateView -> refreshData
                
                main [fillcolor="#e6f3ff"]
                parseData [fillcolor="#f0f8ff"]
                processData [fillcolor="#f0f8ff"]
                renderUI [fillcolor="#f0f8ff"]
            }
        `;

        const graphviz = d3.select("#graph")
            .graphviz()
            .zoom(true)
            .fit(true);

        graphviz.renderDot(defaultData);

        function updateGraph() {
            const newData = `
                digraph {
                    // 设置全局节点样式为矩形
                    node [
                        shape="rect"
                        style="filled"
                        fillcolor="#f0f8ff"
                        width=1.5
                        height=0.5
                        fontsize=12
                    ]
                    
                    // 设置图形布局方向和间距
                    graph [
                        rankdir="TB"
                        nodesep=0.3
                        ranksep=0.4
                    ]
                    
                    // 设置边的样式
                    edge [
                        arrowsize=0.8
                    ]
                    
                    main -> parseData
                    main -> processData
                    main -> renderUI
                    parseData -> validateInput
                    parseData -> formatData
                    processData -> calculateMetrics
                    processData -> filterResults
                    renderUI -> createLayout
                    renderUI -> updateView
                    createLayout -> setupComponents
                    updateView -> refreshData
                    calculateMetrics -> analyzeData
                    analyzeData -> generateReport
                    
                    main [fillcolor="#e6f3ff"]
                    parseData [fillcolor="#f0f8ff"]
                    processData [fillcolor="#f0f8ff"]
                    renderUI [fillcolor="#f0f8ff"]
                    analyzeData [fillcolor="#e6f3ff"]
                    generateReport [fillcolor="#e6f3ff"]
                }
            `;
            
            graphviz.renderDot(newData);
        }
    </script>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值