D3 путь - разделить на 2 новых пути - PullRequest
0 голосов
/ 09 апреля 2020

Я работаю с диаграммой узлов, направленной на Силу, используя d3 js. Я бы хотел использовать атрибут marker-mid на путях, но, по-видимому, в FireFox и Safari есть ошибка, поэтому маркеры не отображаются. Эта ошибка, по-видимому, ограничена маркером-серединой, так как маркер-конец и маркер-начало отрисовываются просто отлично.

Так что, если кто-то не поделится решением, я прибегаю к обходному пути. Моя идея состоит в том, чтобы разбить ar c на 2 отдельных пути и использовать атрибут marker-end.

Ниже приведено описание функции Tick

function linkArc(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x +     "," + d.target.y;
}`

Когда я ее читаю , linkAr c - генерирует точки между двумя узлами. Как я могу изменить эту функцию, чтобы генерировать путь от начальной до средней точки? (затем в другом вызове, от середины до конца)

Я думаю о вызове 2 функций вместо одной

  • linkArcA = PathA начинается в исходном узле и заканчивается в средняя точка
  • linkArcB = PathB начинается в средней точке и заканчивается в целевом узле

В противном случае я открыт для любого альтернативного решения.

1 Ответ

0 голосов
/ 09 апреля 2020

Мне удалось создать работающее решение, которое могло бы помочь другим, пытающимся преодолеть эту ошибку.

Основные действия

  • Создать 2 пути для каждого узла - путь A как первый половина пути, путь B как вторая половина пути.
  • Запустите linkAr c для PathA. Создает полный изогнутый путь
  • Перебирает все PathA и pu sh их средние точки в массиве
  • Запускает linkArcStart, создавая пути от начала до середины
  • Выполнить LinkArcEnd создание путей от средних точек до начала

Вот фрагменты используемого кода

pathA = svg.append("g").selectAll("path")
.data(force.links())
.enter()
.append("path")

pathB = svg.append("g").selectAll("path")
.data(force.links())
.enter()
.append("path")

var mpts = [];

function tick() {
  pathA.attr("d", linkArc);

  pathA.attr("mpts",function(d,i){
    var p = d3.select(this).node()
    var pt = p.getPointAtLength(p.getTotalLength()/2)
    mpts[i] = [pt.x,pt.y];
  })

  pathA.attr("d", linkArcStart);
  pathB.attr("d",linkArcEnd)
 }

function linkArc(d) {
 var dx = (d.target.x - d.source.x) ,
  dy = (d.target.y - d.source.y),
  dr = Math.sqrt(dx * dx + dy * dy),
  pts = "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 "      + d.target.x + "," + d.target.y
 return pts;
}
function linkArcStart(d,i) {
  dx = (d.target.x - d.source.x) ,
  dy = (d.target.y - d.source.y),
  dr = Math.sqrt(dx * dx + dy * dy),
  pts = "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + mpts[i][0]+ "," + mpts[i][1]
 return pts;
}
function linkArcEnd(d,i) {
  dx = (d.target.x - d.source.x) ,
  dy = (d.target.y - d.source.y),
  dr = Math.sqrt(dx * dx + dy * dy),
  pts = "M" + + mpts[i][0]+ "," + mpts[i][1] + "A" + dr + "," + dr + " 0 0,1 " + d.target.x+ "," + d.target.y
  return pts;
}

Надеюсь, что это помогает другим, кто пытается создать маркер-середину, который визуализируется в все браузеры (на Ма c)

...