Проверьте расположение файла libjvm.dylib.
Попробуйте это, в моем случае это сработало:
dyn.load('/Library/Java/JavaVirtualMachines/jdk-10.jdk/Contents/Home/lib/server/libjvm.dylib')
library(rJava)
Вместо размещения маркера на конце создайте свои линии (<polyline>
или <path>
) с одной точкой в середине строки и используйте marker-mid
, чтобы применить стрелки .
Эта демонстрация для в этом ответе использует этот метод для создания нескольких внутренних точек вдоль длины пути вместе с marker-mid
. Вы просто создавали бы одну «путевую точку», а не многие.
Изменить: вот простой взлом существующей демонстрации, показывающий, что я имею в виду:
[/g6]
Единственные изменения:
marker-end
на marker-mid
и ] Это потребует некоторой простой тригонометрии, такой как Superboggly, которая отображает подходящую середину, основанную на размере поклонения, которое вы хотите в своих линиях.
Я сделал несколько иной подход от Phrogz. Я попытался удалить маркер пути и вместо этого нарисую его, используя новый путь, который идет в середину дуги и чей ход невидим. Вычисление средней точки немного затруднительно, поэтому, если вы хотите изменить характеристики дуги, вам может быть лучше подан подход Phrogz или какой-то гибрид.
В этом случае триггер не так уж плох, потому что если вы посмотрите внимательно, вы заметите, что дуга, используемая для генерации ссылок, связана с кругом с тем же радиусом и расстоянием между узлами. Таким образом, у вас есть равносторонний треугольник, и все, что вам нужно сделать, это вычислить расстояние, пройденное срединной точкой сегмента линии линии связи до средней точки дуги.
Я думаю, мне нужна диаграмма для объяснения:
[/g1] Таким образом, треугольник ABC является равносторонним и EC bisect AB. Так как у нас есть координаты для А и В, то найти M легко (усредним координаты). Это означает, что мы также знаем наклон от A до B (delta y / delta x), поэтому наклон от M до E является отрицательным обратным. Знание М и наклон к E означает, что мы почти там, нам просто нужно знать, как далеко продвинуться.
Для этого мы используем тот факт, что ACM представляет собой треугольник 30-60-90, и поэтому
| CM | = sqrt (3) * | AM |
, но | AM | = | AB | / 2 и | CE | = | AB |
Итак,
| ME | = | AB | - sqrt (3) * | AB | / 2
Для того, чтобы эта длина имела смысл, нам придется ее нормализовать с длиной вектора наклона, которую мы уже знаем, совпадает с радиусом круга.
В любом случае, соединяя все это:
var markerPath = svg.append("svg:g").selectAll("path.marker")
.data(force.links())
.enter().append("svg:path")
.attr("class", function(d) { return "marker_only " + d.type; })
.attr("marker-end", function(d) { return "url(#" + d.type + ")"; });
... later in the tick handler
markerPath.attr("d", function(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
// We know the center of the arc will be some distance perpendicular from the
// link segment's midpoint. The midpoint is computed as:
var endX = (d.target.x + d.source.x) / 2;
var endY = (d.target.y + d.source.y) / 2;
// Notice that the paths are the arcs generated by a circle whose
// radius is the same as the distance between the nodes. This simplifies the
// trig as we can simply apply the 30-60-90 triangle rule to find the difference
// between the radius and the distance to the segment midpoint from the circle
// center.
var len = dr - ((dr/2) * Math.sqrt(3));
// Remember that is we have a line's slope then the perpendicular slope is the
// negative inverse.
endX = endX + (dy * len/dr);
endY = endY + (-dx * len/dr);
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + endX + "," + endY;
});
Проверьте здесь . Обратите внимание, что мой путь css для пути маркера установлен на прозрачный красный цвет, обычно вы хотите установить штрих в «none», чтобы скрыть линии.
Я ОП, этот ответ - просто дополнение к превосходным ответам выше ради других с тем же вопросом.
Ответы показывают, как это сделать для графика с дугами. Если у вас прямые ссылки, принятый ответ нужно немного изменить. Вот как:
Ваши прямые ссылки, вероятно, реализованы с помощью line
, их нужно преобразовать в polyline
. Например:
// old: svg.selectAll(".link").data(links).enter().append("line")
svg.selectAll(".link").data(links).enter().append("polyline")
Затем мы должны кодировать полилинию в соответствии с этим примером , поэтому ваш исходный код, который кодирует line
:
force.on("tick", function() {
link.attr("x1", function(d) {return d.source.x;})
.attr("y1", function(d) {return d.source.y;})
.attr("x2", function(d) {return d.target.x;})
.attr("y2", function(d) {return d.target.y;});
Изменяется на:
force.on("tick", function() {
link.attr("points", function(d) {
return d.source.x + "," + d.source.y + " " +
(d.source.x + d.target.x)/2 + "," + (d.source.y + d.target.y)/2 + " " +
d.target.x + "," + d.target.y; });
И, наконец, не забудьте преобразовать marker-end
в marker-mid
:
// old: link.attr("marker-end",
link.attr("marker-mid",
Кредиты на @Phrogz для показа способ.