如何在Python Dash的html.Div中渲染sigma.js图形?
问题描述
我希望构建一个带有sigma.js图形的Python Dash应用,因此尝试运行一个最简示例。我的文件夹结构如下:
DashGraph/ ├── app3.py └── assets └── sigma.min.js
我的代码如下:
import dash from dash import dcc from dash import html from dash.dependencies import Input, Output app = dash.Dash(__name__, suppress_callback_exceptions=True, assets_folder='assets') app.layout = html.Div( [ html.H2("Sigma.js Graph"), html.Div( id="graph-container", children=[ html.Div(id="sigma-container", style={"width": "100%", "height": "500px", "border": "1px solid #ccc"}), ], ), html.Button("Load Graph", id="load-graph-button"), dcc.Location(id='url', refresh=False), html.Div(id='page-content') ] ) init_sigma_script = """ function initSigmaGraph() { if (typeof sigma === 'undefined') { console.error('Sigma.js is not loaded'); return; } // Initialize sigma.js with example data var s = new sigma({ graph: { nodes: [ { id: 'n0', label: 'Node 0', x: 0, y: 0, size: 3 }, { id: 'n1', label: 'Node 1', x: 1, y: 1, size: 3 }, { id: 'n2', label: 'Node 2', x: 2, y: 2, size: 3 }, ], edges: [ { id: 'e0', source: 'n0', target: 'n1' }, { id: 'e1', source: 'n1', target: 'n2' }, { id: 'e2', source: 'n2', target: 'n0' }, ] }, container: 'sigma-container', settings: { defaultNodeColor: '#ec5148' } }); // Add interactivity s.bind('clickNode', function(e) { alert('Node clicked: ' + e.data.node.label); }); } """ @app.callback( Output("graph-container", "children"), [Input("load-graph-button", "n_clicks")], ) def load_graph(n_clicks): if n_clicks is None or n_clicks == 0: return dash.no_update return html.Div( [ html.Div(id="sigma-container", style={"width": "100%", "height": "500px", "border": "1px solid #ccc"}), html.Script(init_sigma_script), html.Script("initSigmaGraph();"), ] ) if __name__ == "__main__": app.run_server(debug=True)
请问如何让sigma图形能够在html.Div中渲染?
解决方案
你的代码存在几个关键问题,调整后即可正常渲染sigma图形:
避免重复创建容器ID
点击按钮后重新创建sigma-container会导致页面出现多个相同ID元素,sigma无法正确定位。应保留初始容器,仅注入初始化脚本。确保sigma.js加载完成后执行初始化
虽然Dash会自动加载assets文件夹资源,但脚本执行时机可能早于sigma.js加载完成,需保证初始化逻辑在sigma之后运行。修正回调逻辑
回调无需替换整个graph-container的子元素,只需添加初始化脚本即可,同时处理重复点击的情况(销毁旧实例)。
修改后的完整代码如下:
import dash from dash import dcc, html, Input, Output app = dash.Dash(__name__, suppress_callback_exceptions=True, assets_folder='assets') app.layout = html.Div( [ html.H2("Sigma.js Graph"), html.Div( id="graph-container", children=[ html.Div(id="sigma-container", style={"width": "100%", "height": "500px", "border": "1px solid #ccc"}), ], ), html.Button("Load Graph", id="load-graph-button"), # 隐藏容器存储初始化脚本,避免重复注入 html.Div(id="sigma-script-holder", style={"display": "none"}), dcc.Location(id='url', refresh=False), html.Div(id='page-content') ] ) init_sigma_script = """ function initSigmaGraph() { // 销毁已存在的sigma实例,避免重复创建 if (window.sigmaInstance) { window.sigmaInstance.kill(); } if (typeof sigma === 'undefined') { console.error('Sigma.js is not loaded'); return; } // 初始化sigma.js,调整节点大小和坐标让图形更明显 window.sigmaInstance = new sigma({ graph: { nodes: [ { id: 'n0', label: 'Node 0', x: 0, y: 0, size: 15 }, { id: 'n1', label: 'Node 1', x: 150, y: 100, size: 15 }, { id: 'n2', label: 'Node 2', x: 300, y: 0, size: 15 }, ], edges: [ { id: 'e0', source: 'n0', target: 'n1' }, { id: 'e1', source: 'n1', target: 'n2' }, { id: 'e2', source: 'n2', target: 'n0' }, ] }, container: 'sigma-container', settings: { defaultNodeColor: '#ec5148', labelThreshold: 10, // 确保节点标签显示 defaultEdgeColor: '#ccc' } }); // 节点点击交互 window.sigmaInstance.bind('clickNode', function(e) { alert('Node clicked: ' + e.data.node.label); }); } """ @app.callback( Output("sigma-script-holder", "children"), Input("load-graph-button", "n_clicks"), prevent_initial_call=True ) def load_graph(n_clicks): return [ html.Script(init_sigma_script), html.Script("initSigmaGraph();") ] if __name__ == "__main__": app.run_server(debug=True)
额外检查事项:
- 确认
sigma.min.js是完整可用的稳定版本 - 打开浏览器开发者工具(F12),在Console标签查看是否有加载错误
- 在Network标签确认
sigma.min.js已成功加载(状态码200)
内容的提问来源于stack exchange,提问作者user56591
相关产品推荐
相关产品推荐

