Используйте настраиваемую силу центра с параметром силы.
.force("center", myCenterForce(this.props.width / 2, this.props.height / 2))
В функциях перетаскивания вызовите
simulation.force("center").strength(0);
simulation.force("center").strength(1.0);
Или вы можете анимировать / интерполировать силу в функции тика.
var dragNode = null;
drag = simulation => {
const dragStarted = function (d) {
if (!d3.event.active) {
simulation.alphaTarget(0.7).restart()
}
dragNode = null;
d.fx = d.x
d.fy = d.y
}
const dragged = function (d) {
d.fx = d3.event.x
d.fy = d3.event.y
}
const dragEnded = function (d) {
if (!d3.event.active) simulation.alphaTarget(0);
dragNode = this;
d3.select(this).attr("data-strength", 0)
.transition().duration(2000)
.attr("data-strength", 1.0)
.on("end", function () { dragNode = null; } );
d.fx = null
d.fy = null
}
return d3
.drag()
.on("start", dragStarted)
.on("drag", dragged)
.on("end", dragEnded)
}
function tick() {
if (dragNode)
simulation.force("center")
.strength(d3.select(dragNode).attr("data-strength"));
// update nodes
}
Пользовательская сила
function myCenterForce(x, y) {
var nodes;
var strength = 1.0;
if (x == null) x = 0;
if (y == null) y = 0;
function force() {
var i,
n = nodes.length,
node,
sx = 0,
sy = 0;
for (i = 0; i < n; ++i) {
node = nodes[i], sx += node.x, sy += node.y;
}
for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) {
node = nodes[i], node.x -= strength * sx, node.y -= strength * sy;
}
}
force.initialize = function(_) {
nodes = _;
};
force.x = function(_) {
return arguments.length ? (x = +_, force) : x;
};
force.y = function(_) {
return arguments.length ? (y = +_, force) : y;
};
force.strength = function(_) {
return arguments.length ? (strength = +_, force) : strength;
};
return force;
}
Что-то вроде этого работало бы:
while(<STDIN>) {
my $line = $_;
chomp($line);
my ($email,$reason) = split(/\|/, $line);
print "Email: $email\n";
print "Reason: $reason";
my $sth = $dbh->prepare(qq{INSERT INTO bademails VALUES(?, ?)});
$sth->execute($email, $reason);
$sth->finish();
}
Вы могли бы найти легче просто сделать все это в Perl. "затем, если / 550 /" не мог заменить grep, и regex мог, вероятно, заменить awk.
Имейте Вас рассмотренное использование Приложение:: Ack вместо этого? Вместо того, чтобы выйти из оболочки к внешней программе, можно просто использовать Perl вместо этого. К сожалению, необходимо будет прочитать ack код программы для реального получения смысла того, как сделать это, но необходимо получить более портативную программу в результате.
Я не уверен, что Вы хотите вставить @list? Если awk передаст одну строку по каналу на запись, то у Вас будет это в $line, и Вам не нужно для цикла на @list.
Тем не менее, если Вы собираетесь передать его по каналу в Perl, почему беспокойство с grep и AWK во-первых?
#!/ust/bin/perl -w
use strict;
while (<>) {
next unless / 550 /;
my @tokens = split ' ', $_;
my $addr = $tokens[4];
my $reason = join " ", @tokens[5..$#tokens];
# ... DBI code
}
Примечание стороны о вызовах DBI: необходимо действительно использовать заполнителей так, чтобы "плохое электронное письмо" не могло бы ввести SQL в базу данных.
Почему бы не воздерживаться от grep и awk и переходить прямо к Perl?
Отказ от ответственности: Я не проверил, компилирует ли следующий код:
while (<STDIN>) {
next unless /550/; # skips over the rest of the while loop
my @fields = split;
my $email = $fields[4];
my $reason = join(' ', @fields[22..32]);
...
}
Править: См. комментарий @dland для дальнейшей оптимизации :-)
Надеюсь, это поможет?
my(@list) = split /\|/, $line;
Это генерирует больше чем две записи в @list, если у Вас будут дополнительные символы вертикальной черты в хвосте строки. Чтобы избежать что, используйте:
$line =~ m/^([^|]+)\|(.*)$/;
my(@list) = ($1, $2);
Доллар в regex является возможно лишним, но также и документы 'конец строки'.