В настоящее время я реализую стрелки в своем силовом макете, как это делается в этом примере (http://bl.ocks.org/mbostock/1153292), и это отлично работает. Тем не менее, можно быстро понять, что расположение и размер стрелок жестко закодированы здесь, поскольку узлы никогда не меняют размер.Как я могу динамически изменять положение и размер стрелок направления на направленном макете d3.js?
У меня есть график, в котором я динамически изменяю размеры узлов, и поэтому я хотел бы, чтобы стрелки обновлялись соответственно, поскольку в противном случае они покрываются узлом или закрывают узел или просто не привязаны к узлу.
Существует только одно сообщение, которое я нашел (linking nodes of variable radius with arrows), в котором говорится об этой проблеме. Однако на него не ответили, и ответ, который дает один плакат с краями, заканчивающимися радиусом узла, а не центром, не является тем, что я хочу сделать. Это потребовало бы постоянной перекомпоновки краевых позиций, которые, учитывая количество ребер, которые у меня есть, непрактичны.
Я думал, что это будет относительно просто, но не смогли понять это. Изменение, которое я в настоящее время работает, перемещает создание маркера ниже генерации узлов, поскольку в противном случае нет возможности получить данные о размере узла, если я не хочу использовать метод размера, который я использую, что было бы огромной тратой (у меня сотни узлов).
То, что я пытаюсь (грубый пример, мой код немного сложнее)
var path = svg.append("svg:g").selectAll("path")
.data(force.links())
.enter().append("svg:path")
.attr("class", function(d) { return d.target.nodeID; });
var circle = svg.append("svg:g").selectAll("circle")
.data(force.nodes())
.enter().append("svg:circle")
.attr("r", nodeSize) //Dynamically determine size
.call(force.drag);
// Per-node markers, as each node could potentially have a unique size
svg.append("svg:defs").selectAll("marker")
.data(nodes, function(d) { return d.nodeID; })
.enter().append("svg:marker")
.attr("id", function(d) { return d.nodeID; })
.attr("viewBox", "0 -5 10 10")
.attr("refX", function(d) { return d.r; }) //Offset by the radius of the node
.attr("refY", 0)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
//Now that we know radius data for nodes, add the arrows in
path.each(function(d) {
d.attr("marker-end", function(d) { return "url(#" + d.target.nodeID + ")"; })
});
Кто-нибудь есть идея о том, как лучше идти об этом? Заранее спасибо!
Обновление: по запросу, я создал jsfiddle (http://jsfiddle.net/herbstmb/j5wJ7/). Это базовый силовой макет, который я пытаюсь использовать для динамических размеров стрелок.
Не можете ли вы превратить этот фрагмент кода в рабочий [скрипка] (http://jsfiddle.net/)? Похоже, что не так много, и было бы проще, если бы другие попытались найти решение. – Jake
Я создал один. Проверьте обновление в сообщении. Это очень простой силовой макет, который я просто пытаюсь добавить стрелки с динамическим размером. –
Консоль ошибки синтаксиса жалуется на предыдущую строку, где вы открываете строку с одной кавычкой и закрываете ее двойной кавычкой. Что касается вашей проблемы, я заметил, что вы сделали пару комментариев об отказе от потенциальных решений из-за потенциальных проблем производительности, запущенных на сотнях узлов. Вероятно, вы должны попросить простейшее решение и проверить его, прежде чем отбрасывать его. Вы будете удивлены, сколько вы можете сделать против пары сотен очков за долю секунды.В наши дни браузеры быстрые (даже мобильные, относительно говоря). –