Я использовал d3-graphviz для рисования интерактивных графиков. Я обнаружил, что использование того же графического рендерера, созданного в начале, чтобы перерисовать новый / обновленный график, приводит к неправильной компоновке. Например, если я сделаю следующие шаги, все пойдет не так:
- Создайте index.html, включая d3, d3-graphviz и viz, которые нам нужно использовать.
- Использовать функцию renderDot () с определенным обратным вызовом.
- Снова вызовите renderDot (), чтобы нарисовать еще одну, с многострочным, жирным шрифтом
- Выполните рендеринг снова с renderDot (), чтобы сгенерировать тот же график, что и на шаге 2
Я должен получить в самом конце, опять же:
Однако, последний шаг (шаг 4) приводит к неправильной схеме размещения. Узлы и ребра не будут размещены в правильных положениях:
Также обратите внимание, что после шага 3, если я нажму на svg, он немного сместится вверх (в одном направлении), что тоже странно. После того, как мы нажмем на него, оно будет выглядеть так:
Вот исходный код:
index.html:
<!-- language: lang-html -->
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src=https://d3js.org/d3.v5.min.js></script>
<script src=https://unpkg.com/viz.js@1.8.0/viz.js></script>
<script src=https://unpkg.com/d3-graphviz@1.5.0/build/d3-graphviz.min.js></script>
<!-- Main Graph -->
<div id="graph" style="text-align: center;" height=3200px width=3200px></div>
</body>
render.js:
<!-- language: typescript -->
// please run below code step by step
// create renderer
x = d3.select('#graph').graphviz()
// 1st rendering
x.renderDot(`
digraph {
node [style="filled"]
0 [id="0" label="honda::models"]
1 [id="1" label="hidden"]
2 [id="2" label="hidden"]
0 -> 1 [id="0->1" label=""]
0 -> 2 [id="0->2" label=""]
}
`, function() {
d3.selectAll('text')._groups[0].forEach(function(e) {
if (ans=/(.+?\: ).+/.exec(e.innerHTML)) {
e.innerHTML = ans[0].replace(ans[1],
"<tspan font-weight=bold>" + ans[1] + "</tspan>");
}
})
});
// 2nd rendering (bold and multi-line text label)
x.renderDot(`
digraph {
node [style="filled"]
0 [id="0" label="honda::models"]
1 [id="1" label="name: fit\\linventory id: 007"]
2 [id="2" label="hidden"]
0 -> 1 [id="0->1" label=""]
0 -> 2 [id="0->2" label=""]
}
`, function() {
d3.selectAll('text')._groups[0].forEach(function(e) {
if (ans=/(.+?\: ).+/.exec(e.innerHTML)) {
e.innerHTML = ans[0].replace(ans[1],
"<tspan font-weight=bold>" + ans[1] + "</tspan>");
}
})
});
// 3rd rendering
x.renderDot(`
digraph {
node [style="filled"]
0 [id="0" label="honda::models"]
1 [id="1" label="hidden"]
2 [id="2" label="hidden"]
0 -> 1 [id="0->1" label=""]
0 -> 2 [id="0->2" label=""]
}
`, function() {
d3.selectAll('text')._groups[0].forEach(function(e) {
if (ans=/(.+?\: ).+/.exec(e.innerHTML)) {
e.innerHTML = ans[0].replace(ans[1],
"<tspan font-weight=bold>" + ans[1] + "</tspan>");
}
})
});
Вы можете скопировать его, создав index.html, а затем пошагово запустив код в javascript.
Примечание: я оставил там функцию обратного вызова, которая обновляет шрифт, если в каждой строке он видит шаблоны "text: xxx". Не имеет значения в «скрытом» корпусе.
Спасибо!