Use d3-graphviz for rendering crates graph on the extension side

This commit is contained in:
André Oliveira 2021-08-10 13:34:30 +00:00
parent e1dcec0e02
commit f4f68e62c2
3 changed files with 33 additions and 15 deletions

View file

@ -133,18 +133,9 @@ pub(crate) fn handle_view_crate_graph(
let _p = profile::span("handle_view_crate_graph");
let dot = snap.analysis.view_crate_graph(params.full)??;
// We shell out to `dot` to render to SVG, as there does not seem to be a pure-Rust renderer.
let child = Command::new("dot")
.arg("-Tsvg")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.map_err(|err| format!("failed to spawn `dot`: {}", err))?;
child.stdin.unwrap().write_all(dot.as_bytes())?;
eprintln!("{}", dot);
let mut svg = String::new();
child.stdout.unwrap().read_to_string(&mut svg)?;
Ok(svg)
Ok(dot)
}
pub(crate) fn handle_expand_macro(

View file

@ -38,7 +38,9 @@
"dependencies": {
"https-proxy-agent": "^5.0.0",
"node-fetch": "^2.6.1",
"vscode-languageclient": "^7.1.0-next.5"
"vscode-languageclient": "^7.1.0-next.5",
"d3": "^7.0.0",
"d3-graphviz": "^4.0.0"
},
"devDependencies": {
"@types/glob": "^7.1.4",

View file

@ -472,12 +472,37 @@ export function viewItemTree(ctx: Ctx): Cmd {
function crateGraph(ctx: Ctx, full: boolean): Cmd {
return async () => {
const panel = vscode.window.createWebviewPanel("rust-analyzer.crate-graph", "rust-analyzer crate graph", vscode.ViewColumn.Two);
const panel = vscode.window.createWebviewPanel("rust-analyzer.crate-graph", "rust-analyzer crate graph", vscode.ViewColumn.Two, {
enableScripts: true,
retainContextWhenHidden: true
});
const params = {
full: full,
};
const svg = await ctx.client.sendRequest(ra.viewCrateGraph, params);
panel.webview.html = svg;
const dot = await ctx.client.sendRequest(ra.viewCrateGraph, params);
console.log(dot);
const html = `
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://unpkg.com/@hpcc-js/wasm@0.3.11/dist/index.min.js"></script>
<script src="https://unpkg.com/d3-graphviz@3.0.5/build/d3-graphviz.js"></script>
<div id="graph" style="text-align: center;"></div>
<script>
let margin = 0;
d3.select("#graph").graphviz().fit(true).width(window.innerWidth - margin).height(window.innerHeight - margin)
.renderDot(\`${dot}\`);
</script>
</body>
`;
console.log(html);
panel.webview.html = html;
};
}