D3 версия 5 принудительная компоновка с фиксированными узлами [дубликат]

Когда вы объявляете ссылочную переменную (т. е. объект), вы действительно создаете указатель на объект. Рассмотрим следующий код, в котором вы объявляете переменную примитивного типа int:

int x;
x = 10;

В этом примере переменная x является int, и Java инициализирует ее для 0. Когда вы назначаете его 10 во второй строке, ваше значение 10 записывается в ячейку памяти, на которую указывает x.

Но когда вы пытаетесь объявить ссылочный тип, произойдет что-то другое. Возьмите следующий код:

Integer num;
num = new Integer(10);

Первая строка объявляет переменную с именем num, но она не содержит примитивного значения. Вместо этого он содержит указатель (потому что тип Integer является ссылочным типом). Поскольку вы еще не указали, что указать на Java, он устанавливает значение null, что означает «Я ничего не указываю».

Во второй строке ключевое слово new используется для создания экземпляра (или создания ) объекту типа Integer и переменной указателя num присваивается этот объект. Теперь вы можете ссылаться на объект, используя оператор разыменования . (точка).

Exception, о котором вы просили, возникает, когда вы объявляете переменную, но не создавали объект. Если вы попытаетесь разыменовать num. Перед созданием объекта вы получите NullPointerException. В самых тривиальных случаях компилятор поймает проблему и сообщит вам, что «num не может быть инициализирован», но иногда вы пишете код, который непосредственно не создает объект.

Например, вы можете имеют следующий метод:

public void doSomething(SomeObject obj) {
   //do something to obj
}

В этом случае вы не создаете объект obj, скорее предполагая, что он был создан до вызова метода doSomething. К сожалению, этот метод можно вызвать следующим образом:

doSomething(null);

В этом случае obj имеет значение null. Если метод предназначен для того, чтобы что-то сделать для переданного объекта, целесообразно бросить NullPointerException, потому что это ошибка программиста, и программисту понадобится эта информация для целей отладки.

Альтернативно, там могут быть случаи, когда цель метода заключается не только в том, чтобы работать с переданным в объекте, и поэтому нулевой параметр может быть приемлемым. В этом случае вам нужно будет проверить нулевой параметр и вести себя по-другому. Вы также должны объяснить это в документации. Например, doSomething может быть записано как:

/**
  * @param obj An optional foo for ____. May be null, in which case 
  *  the result will be ____.
  */
public void doSomething(SomeObject obj) {
    if(obj != null) {
       //do something
    } else {
       //do something else
    }
}

Наконец, Как определить исключение & amp; причина использования Трассировки стека

59
задан Infinite Recursion 18 June 2014 в 16:18
поделиться

2 ответа

Установите d.fixed на нужных узлах в значение true и инициализируйте d.x и d.y в нужную позицию. Эти узлы будут по-прежнему оставаться частью моделирования, и вы можете использовать обычный код отображения (например, установить атрибут преобразования); однако, поскольку они отмечены как фиксированные, их можно перемещать только с помощью перетаскивания, а не с помощью имитации.

Подробнее см. документацию force , а также посмотреть, как корневой узел находится в в этом примере .

70
ответ дан mbostock 17 August 2018 в 10:08
поделиться

Фиксированные узлы в силовой компоновке для d3v4 и d4v5

В d3v3 d.fixed будут фиксированы узлы в d.x и d.y; однако в d3v4 / 5 этот метод больше не поддерживается. В документации d3 указано:

. Чтобы исправить узел в данной позиции, вы можете указать два дополнительных свойства:

fx - the node’s fixed x-position

fy - the node’s fixed y-position

В конце каждого тика после применения любых сил узел с определенным узлом.fx имеет node.x сбрасывается на это значение и устанавливается node.vx до нуля; Аналогично, узел с определенным узлом.fy имеет node.y сбрасывается на это значение, а node.vy устанавливается на ноль. Чтобы исключить ранее установленный узел, установите node.fx и node.fy в значение null или удалите эти свойства.

Вы можете установить атрибуты fx и fy для силы узлов в вашем источнике данных, или вы можете динамически добавлять и удалять значения fx и fy. Ниже приведенный ниже фрагмент устанавливает эти свойства в конце событий перетаскивания, просто перетащите узел, чтобы зафиксировать его положение:

var data ={ 
 "nodes": 
  [{"id": "A"},{"id": "B"},{"id": "C"},{"id":"D"}], 
 "links": 
  [{"source": "A", "target": "B"}, 
   {"source": "B", "target": "C"},
   {"source": "C", "target": "A"},
   {"source": "D", "target": "A"}]
}
var height = 250;
var width = 400;

var svg = d3.select("body").append("svg")
  .attr("width",width)
  .attr("height",height);
  
var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) { return d.id; }).distance(50))
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(width / 2, height / 2));
    
var link = svg.append("g")
  .selectAll("line")
  .data(data.links)
  .enter().append("line")
  .attr("stroke","black");

var node = svg.append("g")
 .selectAll("circle")
 .data(data.nodes)
 .enter().append("circle")
 .attr("r", 5)
 .call(d3.drag()
   .on("drag", dragged)
   .on("end", dragended));
 
simulation
 .nodes(data.nodes)
 .on("tick", ticked)
 .alphaDecay(0);

simulation.force("link")
 .links(data.links);
      
function ticked() {
 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; });
 node
   .attr("cx", function(d) { return d.x; })
   .attr("cy", function(d) { return d.y; });
}    
    
function dragged(d) {
  d.fx = d3.event.x;
  d.fy = d3.event.y;
}

function dragended(d) {
  d.fx = d3.event.x;
  d.fy = d3.event.y;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.min.js"></script>

16
ответ дан Andrew Reid 17 August 2018 в 10:08
поделиться
  • 1
    Но как d3 знает, что некоторые узлы уже исправлены или нет? Если значение null не является фиксированным, но затем d3 перезаписывает значения fx и fy ... – Aral Roca 15 June 2018 в 11:00
  • 2
    Я не знаю, хорошо ли я понимаю комментарий: если fx или fy не определено или null, узел не будет исправлен, так как я не определяю его для запуска любого из моих узлов, ни один из них не исправлен. D3 не будет перезаписывать значения fx / fy, если вы не сообщите об этом, как я здесь. (Не очень, но я обновил фрагмент, чтобы немного поработать, установив значения fx / fy в dragged вместо установки x / y (так что точка остается с мышью и невосприимчива к другим силам). – Andrew Reid 16 June 2018 в 03:07
Другие вопросы по тегам:

Похожие вопросы: