2016-11-03 3 views
0

У меня есть часть кода, где я хочу увеличивать/уменьшать значения атрибутов объектов d3.Лучший способ увеличить атрибут d3

Я сделал это, используя следующие:

var diff=5; 
d3Selector.attr("x",function(){ 
    return Number(d3Selector.attr("x"))+diff; 
}); 

В JS просто += работы. Есть ли лучший способ сделать это, чем получить текущее значение и добавить и установить его снова?

Данное предложение было создано с предложением Robert Longson и я использую d3_v4. Проблема здесь в том, что они объединены (как строки), а не с добавлением числа, которые я пытался решить, используя Number(), но он дает ошибку, говорящую о Must be lvalue.

function mov() { 
 
    var diffX = 5; 
 
    d3.select("#ee")["_groups"][0][0]["attributes"].x.value += diffX; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.js"></script> 
 
<button onclick="mov()">Click to move</button> 
 
<br> 
 
<svg width="400" height="400"> 
 
    <rect id="ee" x="10" y="10" width="100" height="100" /> 
 
</svg>

+2

d3Selector [0] [0] .x.baseVal.value + = diff; работа для вас. Если не создать скрипт или фрагмент стека, который можно запустить, чтобы я мог показать вам, что делать и проверить свой ответ. –

+0

Нет, но это работает: 'd3child [" _ groups "] [0] [0] [" attributes "]. Cx.value + = diff' – SachiDangalla

+0

@RobertLongson Является ли разница, вызванная изменением версии? Я попытался с d3_v4 и обновил вопрос, добавив фрагмент кода – SachiDangalla

ответ

1

Используйте SVG DOM.

function mov() { 
 
    var diffX = 5; 
 
    d3.select("#ee").node().x.baseVal.value += diffX; 
 

 
    // or alternatively 
 
    // document.getElementById("ee").x.baseVal.value += diffX; 
 
    // as suggested by altocumulus 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.js"></script> 
 
<button onclick="mov()">Click to move</button> 
 
<br> 
 
<svg width="400" height="400"> 
 
    <rect id="ee" x="10" y="10" width="100" height="100" /> 
 
</svg>

+0

. Этот подход основан на доступе к внутренним компонентам D3, которые сильно обескуражены. Выполнение этого без D3 будет быстрее и легче читать: 'document.getElementById (« ee »). X.baseVal.value + = diffX;'. – altocumulus

+0

@altocumulus Я обновил ответ, чтобы не использовать внутренние компоненты, но вместо этого использовать стандартный метод узла d3. –

+0

Поскольку OP явно запросил способ D3, на самом деле это может быть самый точный ответ. – altocumulus

0

D3 и сеттеры геттеры

Я считаю, что понимание того, как методы установки и получения работы в D3 может пролить некоторый свет здесь.

Вы просили лучший способ, чтобы увеличить данный атрибут, вместо «получение текущего значения и добавление и настройки его снова», и вы сказали:

В JS просто + = работает

Итак, почему мы не можем использовать то же самое с помощью D3? Посмотрим.

Учитывая это очень простой код:

var svg = d3.select("body").append("svg"); 

var circle = svg.append("circle").attr("cx", 50) 
    .attr("cy", 50).attr("r", 5); 

Он рисует круг в (50,50). Мы можем получить значение cx этого круга, используя геттер. Геттерный в основном те же функции, но только 1 аргумент:

var x = circle.attr("cx");//returns 50 

Итак, что произойдет, если мы просто добавить значение х, с помощью JS +=?

var x += 100;//returns 50100 

50 + 100 не 50100. Мы только что обнаружили, что значение x является строка, а не число. Для того, чтобы преобразовать его в число давайте сделаем это:

var x = circle.attr("cx"); 
x = +x; 
x += 100; 

Теперь x 150. Мы успешно добавили значение x.

И вот самая важная часть: это не изменит положение круга.x - это просто переменная, которая получает значение этого круга cx с использованием геттера.

Изменение значения x - это значение, изменяющее значение переменной. Это не повлияет на элемент.

Чтобы изменить положение круга (без манипулирования baseVal), мы должны использовать сеттер, то есть функция с 2-мя аргументами:

circle.attr("cx", x);//now the circle moves to (150,50) 

Заключение: что модель (получение текущее значение, добавление чего-то, установка значения снова) может показаться громоздким и не очень элегантным, но это стандартный шаблон в D3.

Смежные вопросы