Golang如何实现动态图表生成?

Golang如何实现动态图表生成? 大家好,

有没有什么工具可以让我创建一个架构图,当我点击其中的某个项目时,它能跳转到另一个图表或网页?

6 回复

感谢 @christophberger,这个仓库太棒了!

更多关于Golang如何实现动态图表生成?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


感谢您的澄清。我也不了解这些工具,但我同意此类工具应提供深入查看图表细节的功能。对我来说,这将是任何架构图工具的必要功能。

我刚刚发现了一个可能很有用的“Awesome Diagramming”仓库:

shubhamgrg04/awesome-diagramming: 软件工程团队使用的图表工具精选集

类似于 C4 模型 吗?C4 涵盖了软件架构的四个层级(因此得名)。

他们在这里列出了图表工具列表:The C4 model for visualising software architecture,用于交互式图表等。

你好 @christophberger

这些都是很好的工具,但我不确定它们是否提供了我想要的功能:图表应该支持嵌入指向其他图表的链接,当我点击这样的链接(例如代表一个微服务的矩形)时,它应该跳转到该链接指向的图表?

有可能所有这些工具都能做到这一点,只是我对它们非常不熟悉。

在Go中实现交互式动态图表生成,可以使用以下两种主流方案:

1. 使用ECharts + Go模板

通过Go生成ECharts配置,实现点击跳转功能:

package main

import (
	"html/template"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		tmpl := template.Must(template.New("chart").Parse(`
<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
</head>
<body>
    <div id="chart" style="width: 800px;height:600px;"></div>
    <script>
        var chart = echarts.init(document.getElementById('chart'));
        var option = {
            title: { text: '系统架构图' },
            tooltip: {},
            series: [{
                type: 'graph',
                layout: 'force',
                data: [
                    {id: 'api', name: 'API网关', x: 300, y: 100},
                    {id: 'auth', name: '认证服务', x: 100, y: 300},
                    {id: 'order', name: '订单服务', x: 500, y: 300},
                    {id: 'payment', name: '支付服务', x: 300, y: 500}
                ],
                links: [
                    {source: 'api', target: 'auth'},
                    {source: 'api', target: 'order'},
                    {source: 'order', target: 'payment'}
                ],
                emphasis: { focus: 'adjacency' },
                roam: true,
                label: { show: true },
                force: { repulsion: 1000 }
            }]
        };
        
        // 点击事件处理
        chart.on('click', function(params) {
            if (params.dataType === 'node') {
                // 跳转到对应服务的详情页
                window.location.href = '/service/' + params.data.id;
            }
        });
        
        chart.setOption(option);
    </script>
</body>
</html>
		`))
		tmpl.Execute(w, nil)
	})

	// 处理服务详情页
	http.HandleFunc("/service/", func(w http.ResponseWriter, r *http.Request) {
		serviceID := r.URL.Path[len("/service/"):]
		w.Write([]byte("服务详情: " + serviceID))
	})

	http.ListenAndServe(":8080", nil)
}

2. 使用GoJS库(商业用途需授权)

GoJS提供专业的图表交互功能:

package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/gojs-chart", func(w http.ResponseWriter, r *http.Request) {
		html := `
<!DOCTYPE html>
<html>
<head>
    <script src="https://unpkg.com/gojs/release/go.js"></script>
    <script id="code">
        function init() {
            var $ = go.GraphObject.make;
            var diagram = $(go.Diagram, "myDiagramDiv",
                {
                    initialContentAlignment: go.Spot.Center,
                    "undoManager.isEnabled": true
                });

            diagram.nodeTemplate =
                $(go.Node, "Auto",
                    $(go.Shape, "RoundedRectangle",
                        { fill: "lightblue", stroke: "blue", strokeWidth: 2 }),
                    $(go.TextBlock,
                        { margin: 8, font: "bold 14px sans-serif" },
                        new go.Binding("text", "key")),
                    {
                        click: function(e, obj) {
                            var node = obj.part;
                            window.location.href = "/details/" + node.data.key;
                        }
                    }
                );

            diagram.model = new go.GraphLinksModel(
                [
                    { key: "Load Balancer" },
                    { key: "Web Server" },
                    { key: "Database" },
                    { key: "Cache" }
                ],
                [
                    { from: "Load Balancer", to: "Web Server" },
                    { from: "Web Server", to: "Database" },
                    { from: "Web Server", to: "Cache" }
                ]);
        }
    </script>
</head>
<body onload="init()">
    <div id="myDiagramDiv" style="width:800px; height:600px; border:1px solid black"></div>
</body>
</html>`
		fmt.Fprint(w, html)
	})

	http.HandleFunc("/details/", func(w http.ResponseWriter, r *http.Request) {
		service := r.URL.Path[len("/details/"):]
		fmt.Fprintf(w, "显示 %s 的详细架构图", service)
	})

	http.ListenAndServe(":8080", nil)
}

3. 动态生成Mermaid图表

使用Mermaid.js实现可点击的流程图:

package main

import (
	"html/template"
	"net/http"
)

func main() {
	http.HandleFunc("/mermaid", func(w http.ResponseWriter, r *http.Request) {
		tmpl := template.Must(template.New("mermaid").Parse(`
<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.jsdelivr.net/npm/mermaid@10.6.1/dist/mermaid.min.js"></script>
    <script>
        mermaid.initialize({ startOnLoad: true });
        
        function handleClick(nodeId) {
            fetch('/node-click', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify({nodeId: nodeId})
            }).then(response => {
                if (response.redirected) {
                    window.location.href = response.url;
                }
            });
        }
    </script>
    <style>
        .mermaid { cursor: pointer; }
        .node:hover { stroke-width: 3px; }
    </style>
</head>
<body>
    <div class="mermaid">
        graph TD
            A[客户端] --> B[API网关]
            B --> C[用户服务]
            B --> D[订单服务]
            B --> E[支付服务]
            D --> F[(数据库)]
            
            click A "javascript:handleClick('client')"
            click B "javascript:handleClick('api_gateway')"
            click C "javascript:handleClick('user_service')"
            click D "javascript:handleClick('order_service')"
            click E "javascript:handleClick('payment_service')"
            click F "javascript:handleClick('database')"
    </div>
</body>
</html>
		`))
		tmpl.Execute(w, nil)
	})

	http.HandleFunc("/node-click", func(w http.ResponseWriter, r *http.Request) {
		// 解析点击的节点ID,重定向到对应页面
		http.Redirect(w, r, "/architecture/detail", http.StatusSeeOther)
	})

	http.ListenAndServe(":8080", nil)
}

这些方案都支持通过Go后端处理点击事件,实现图表节点到其他图表或网页的跳转。ECharts方案适合开源项目,GoJS提供更专业的图表功能,Mermaid则适合简单的流程图场景。

回到顶部