Scale, Domain и Range

Последнее обновление: 1.11.2015

Ключевой задачей при визуализации данных является их сопоставление с визуальными элементами. Чтобы упростить процесс сопоставления D3 предоставляет специальные конструкции, которые называются scale. Однако роль scale только сопоставлением не ограничивается, они также могут служить в качестве строительных кирпичиков более сложных конструкций в d3.

Что же представляет scale? scale можно представить в качестве математической функции, которая преобразует некоторое значение из одного интервала, который называется domain, в значение, принадлежащее другому интервалу, который называется range.

Рассмотрим простейший пример. Так, у нас есть курс валют. Например, курс рубля по отношению к доллару на некотором временном промежутке изменялся и представляет следующие значения: 64, 62, 63, 59, 60, 57. То есть мы можем прикинуть примерный диапазон разброса значений - от 50 до 70 рублей за доллар. Диапазон от 50 до 70 и будет выполнять роль интервала domain.

Допустим, нам надо представить изменение курса валюты на графике, например, по оси Х. Но чтобы все выглядело более менее нам надо масштабировать интервал [50, 70] на некоторый отрезок оси X, например, на отрезок от 0 до 50. Для этого и надо использовать функцию scale.

С помощью d3 мы можем сделать подобное сопоставление следующим образом:

var data =[64, 62, 63, 59, 60, 57];

var linear = d3.scale.linear()
.domain([50, 70])
.range([1, 50]);

for(var i=0; i<data.length; i++)
	console.log(linear(data[i]));

Функция d3.scale.linear() будет автоматически сопоставлять значения из одного интервала со значениями из другого. В итоге консоль выведет следующие числа:

35.3
30.4
32.85
23.05
25.5
18.15

Эти числа и будут представлять координаты по оси Х.

В качестве scale здесь использовалась линейная функция d3.scale.linear(). Но кроме нее мы можем использовать еще ряд других.

Так, функция d3.scale.pow() возвращает определенную степень числа:

var data =[1, 2, 3, 4, 5];
var pow = d3.scale.pow().exponent(2);

for(var i=0; i<data.length; i++)
	data[i]=pow(data[i]);

console.log(data);

Результатом программы будет следующий вывод:

[ 1, 4, 9, 16, 25 ]

То есть так как в метод .exponent(2) передается двойка, то каждое число из массива возводится во вторую степень, а сама формула будет выглядеть так: f(n) = n^2. В данном случае нам необязательно использовать интервалы domain и range. Однако можно и использовать интервалы, в этом случае формула будет также меняться:

var data =[1, 2, 3, 4, 5];
var pow = d3.scale.pow().exponent(2).domain([1, 10])
.rangeRound([1, 10]);

for(var i=0; i<data.length; i++)
	data[i]=pow(data[i]);

console.log(data);

Вместо метода range здесь применяется метод rangeRound(), который имеет то же самое предназначение, но кроме того позволяет округлять получаемые значения.

Теперь вывод будет другим:

1, 1, 2, 2, 3

А формула будет выглядеть так: f(n) = a*n^2 + b, 1 <= f(n) <= 10.

Также можно использовать логарифмическую интерполяцию с помощью функции d3.scale.log(). По умолчанию используется логарифм по основанию 10:

var data =[1, 10, 100, 1000];
var log = d3.scale.log();

for(var i=0; i<data.length; i++)
	data[i]=log(data[i]);

console.log(data);

Вывод:

0, 1, 2, 2.9999999999999996 

Чтобы сделать числа более ровными, мы можем применять округление с помощью функции d3.round: data[i]=d3.round(log(data[i]))

Еще одна функция d3.time.scale() позволяет сопоставлять линейные интервалы с временными отрезками, то может быть полезно, например, если мы решим вывести по одной оси даты:

var start = new Date(2015, 0, 1), //1 января 2015
end = new Date(2015, 2, 1),  // 1 марта 2015
range = [0, 300]; // интервал значений по оси Х
var data = [ // интервал дат
	new Date(2015, 0, 10),
	new Date(2015, 0, 20),
	new Date(2015, 0, 31),
	new Date(2015, 1, 8),
	new Date(2015, 1, 16)
];

var time = d3.time.scale().domain([start, end]).rangeRound(range);
for(var i=0; i<data.length; i++)
	data[i]=time(data[i]);

console.log(data);

Здесь некоторый набор дат из массива data интерполируется на отрезок от 0 до 300. В итоге мы получим следующий вывод:

46, 97, 153, 193, 234
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850