D3 в тени

Через некоторое время мы довольно предсказуемо используем D3. Настройте холст SVG. Выберите и добавьте элементы. Получите введенные данные. Расположите и измените размер элементов в соответствии с введенными данными. Привязать элементы к новым данным. Закройте и удалите элементы, если данные больше не существуют.

Мы думаем, что можем использовать D3 только таким образом. Но что, если мы хотим использовать способность D3 переводить данные (из области данных в размеры экрана); или мы хотим использовать встроенные возможности функции перехода.

Почему вы хотите это сделать? Вы можете спросить.

Что ж, это позволяет нам использовать многие возможности D3, но использовать другую библиотеку, например three.js, для рисования на экране.

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

Сначала мы создаем массив данных.

var data = [];
var numElements = 50;

for (var i=0; i<numElements; i+=10){
			for (var j=0; j<numElements; j+=10){
		data.push({x:i,y:j});
	  }
}

Затем мы создаем функцию для привязки данных к элементам DOM. Но обратите внимание, что это не настоящие элементы DOM (например, rect или div), отображаемые на экране. Они похожи на теневые элементы DOM, скрытые в фоновом режиме, но с привязанными к ним реальными данными.

function indata(data){
		
		var dataJoin = svg.selectAll('.shadow')
						  .data(data);
		
		var dataEnter = dataJoin.enter()
								.append('custom')
								.attr('class', 'shadow')
								.attr('x',0)
								.attr('y',0)
								.attr('radius', 0);
		
		dataJoin.merge(dataEnter)
				.transition()
				.duration(1000)
				.attr('x',function(d){
				  return d.x;
				})
				.attr('y', function(d){
				  return d.y;
				})
				.attr('radius', function(d){
				  return 500/numElements;
				});
		
		var dataExit = dataJoin.exit()
								.transition()
								.duration(1000)
								.attr('x', 0)
								.attr('y', 0)
								.attr('radius',0)
								.remove();
};

Затем мы «рисуем» данные, привязанные к этим теневым элементам DOM, на экран, находя узлы DOM, к которым они привязаны.

function outdata() {
		var shadowElements = svg.selectAll('custom.shadow');
		
		shadowElements.each(function(d){
		  var node = d3.select(this);
		  // console.log(node.attr('x'));
		  // console.log(node.attr('y'));
		  // console.log(node.attr('radius'));
		 
		d3.select('#text-output')
			.html(function(){
			  return 'Width/Number of Elements=' + node.attr('radius');
			})
		});
};

Мы можем проверить вывод, либо записав их в консоль, либо фактически распечатав значения в div.

Затем, чтобы увидеть переход в действии, мы должны многократно запускать функцию outdata (которая «рисует» материал) в течение определенного периода времени.

indata(data);

var dataTimer = d3.timer(function(elapsed){
	  outdata();
	  if (elapsed>1000) {dataTimer.stop();}
});

Я также вставил поле ввода текста, которое будет принимать новое количество указанных элементов, запускать функции indata и outdata.

d3.select('#text-input').on('keydown', function(){
	  if (d3.event.keyCode === 13){
		data = [];
		numElements = +this.value;
		for (var i=0; i<numElements; i+=10){
				for (var j=0; j<numElements; j+=10){
			data.push({x:i,y:j});
		  }
		}
		// console.log(data.length);
		indata(data);
		var dataTimer = d3.timer(function(elapsed){
		  outdata();
		  if (elapsed>1000) {dataTimer.stop();}
		});   
	  }
})

Полный код для этого доступен здесь.

Playgrd.com || Facebook.com/playgrdstar || Instagram.com/playgrdstar/