Как использовать Dagre (или аналогичную библиотеку графиков) для построения только краев, учитывающих фиксированные позиJavascript

Форум по Javascript
Ответить
Anonymous
 Как использовать Dagre (или аналогичную библиотеку графиков) для построения только краев, учитывающих фиксированные пози

Сообщение Anonymous »

мне нужно нарисовать график, позиции и размеры узлов, предопределенные (из внешнего источника) и не могут быть изменены. Просто нарисовать узлы, используя библиотеку, такую ​​как D3. Трудность возникает при рисовании краев. Я понимаю, что библиотеки, такие как Dagre , имеют функциональность, чтобы выяснить макет узлов и краев и сделать график представлять. Но для меня задача заключается в использовании Dagre для работы с фиксированными положениями узел < /em> и заставьте его вычислять только пути к крае. />

Код: Выделить всё

// Simple adj list for my graph
const adjList = {
"A": ["B", "C"],
"B": ["D"],
"C": [],
"D": []
};

// Fixed positions.
// This will be from an external source which CANNOT be changed.
// I can't figure out to pass this to dagre's layout engine.
const fixedPositions = {
A: { x: 300, y: 50 },
B: { x: 150, y: 150 },
C: { x: 450, y: 150 },
D: { x: 100, y: 250 }
};

const g = new dagre.graphlib.Graph();
g.setGraph({});
g.setDefaultEdgeLabel(function() { return {}; });

// Adidng nodes and edges to  graph
Object.keys(adjList).forEach(node => {
g.setNode(node, { label: node, width: 50, height: 30 });
});

Object.entries(adjList).forEach(([node, edges]) => {
edges.forEach(target => {
g.setEdge(node, target);
});
});

// Run the layout algorithm (this part computes the layout considering everything and can't be forced to work with my fixed positions)
dagre.layout(g);

// Create the SVG
const svg = d3.select("#graph")
.append("svg")
.attr("width", "100%")
.attr("height", "100%");

const inner = svg.append("g");

// zoom behavior
const zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);

// Create nodes
const nodes = inner.selectAll(".node")
.data(g.nodes())
.enter()
.append("g")
.attr("class", "node")
.attr("transform", function(v) {
const node = g.node(v);
return `translate(${node.x}, ${node.y})`;
});

// draw rectangles for nodes
nodes.append("rect")
.attr("width", function(v) { return g.node(v).width; })
.attr("height", function(v) { return g.node(v).height; })
.attr("x", function(v) { return -g.node(v).width / 2; })
.attr("y", function(v) { return -g.node(v).height / 2; });

// print labels for nodes
nodes.append("text")
.attr("text-anchor", "middle")
.attr("dominant-baseline", "central")
.text(function(v) { return v; });

// Create edges (this will use dagre's layout below)
const line = d3.line()
.x(d => d.x)
.y(d =>  d.y)
.curve(d3.curveBasis);

const edges = inner.selectAll(".edge")
.data(g.edges())
.enter()
.append("path")
.attr("class", "edge")
.attr("d", function(e) {
const edge = g.edge(e);
return line(edge.points);
});

const graphBounds = inner.node().getBBox();
const width = svg.node().clientWidth;
const height = svg.node().clientHeight;
const scale = Math.min(width / graphBounds.width, height / graphBounds.height) * 0.9;
const translate = [
(width - graphBounds.width * scale) / 2 - graphBounds.x * scale,
(height - graphBounds.height * scale) / 2 - graphBounds.y * scale
];

svg.call(zoom.transform, d3.zoomIdentity
.translate(translate[0], translate[1])
.scale(scale));< /code>
#graph {
width: 100%;
height: 600px;
background-color: #f9f9f9;
}
.node rect {
stroke: #333;
fill: #fff;
stroke-width: 1px;
}
.node text {
font: 12px sans-serif;
}
.edge {
stroke: #333;
stroke-width: 1px;
fill: none;
}< /code>



Simple Graph








Моя единственная проблема с этим заключается в том, что, похоже, нет способа передать мои фиксированные разложения , чтобы заставить их использовать их для размещения узлов, а затем сделать макет только для регенсов. const fixedPositions = {
A: { x: 300, y: 50 },
B: { x: 150, y: 150 },
C: { x: 450, y: 150 },
D: { x: 100, y: 250 }
};

// cannot do
// dagre.layout(g, fixedPositions);
< /code>
Есть ли способ достичь этого либо с Dagre, либо с какой -либо другой библиотекой? Этот вопрос задает об этом в теоретической перспективе, но я спрашиваю в более практичном смысле с использованием доступных библиотек с открытым исходным кодом или иным образом. Например, это может быть результатом, если я вручную нарисую ребра прямой линии для другого (не единственного в моем коде).>

Подробнее здесь: https://stackoverflow.com/questions/796 ... s-given-fi
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»