2015-04-21 3 views
24
var xScale = d3.scale.ordinal().domain([0, d3.max(data)]).rangeRoundBands([0, w], .1); 
var yScale = d3.scale.linear().domain([0, data.length]).range([h, 0]); 

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

Ниже приведено то, что я обнаружил из документа API, все еще потерянного ... если кто-то может помочь, это было бы очень признательно.

порядковые (х)

Учитывая значение х в области ввода, возвращает соответствующее значение в выходном диапазоне.

Если диапазон был указан явно (как диапазон, а не диапазон диапазонов, rangeRoundBands или rangePoints), а заданное значение x не находится в домене шкалы, то x неявно добавляется в домен; последующие вызовы шкалы с одинаковым значением x возвращают то же значение y из диапазона.

d3.scale.linear()

конструирует новый линейная шкала с областью по умолчанию [0,1] и диапазона по умолчанию [0,1]. Таким образом, линейная шкала по умолчанию эквивалентна функции идентификации для чисел; например, линейный (0,5) возвращает 0,5.

+1

Линейная шкала будет интерполировать между входными значениями, тогда как порядковой шкалы не будет. –

+0

@ LarsKotthoff, пожалуйста, укажите пример? – Bruce

+0

На самом деле есть пример этого в документах 'linear (0.5)'. –

ответ

44

Как для Ordinal Scales:

Порядковые шкалы имеют дискретный домен, такие как набор имен или категорий.

Значения порядковой шкалы должны быть принудительными для строки, а строчная версия значения домена однозначно идентифицирует соответствующее значение диапазона.

Так, в качестве примера, домен порядковой шкалы может содержать имена, например, так:

var ordinalScale = d3.scale.ordinal() 
     .domain(['Alice', 'Bob']) 
     .range([0, 100]); 

ordinalScale('Alice'); // 0 
ordinalScale('Bob'); // 100 

Обратите внимание, как все значения являются строками. Они не могут быть интерполированы. Что между «Алисой» и «Боб»? Я не знаю. Также D3.

Теперь, как и для Quantitative Scales (например Линейные шкалы):

Количественные весы имеют непрерывную область, например, множества действительных чисел или дат.

В качестве примера, можно построить следующую шкалу:

var linearScale = d3.scale.linear() 
     .domain([0, 10]) 
     .range([0, 100]); 

linearScale(0); // 0 
linearScale(5); // 50 
linearScale(10); // 100 

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

Взгляните на this jsfiddle, чтобы увидеть приведенный выше код в действии.

+2

Омг ... вы должны написать d3 API doc, блестящий, полностью понятный. Спасибо, кучи :) – Bruce

+0

Если у вас более двух элементов в вашем домене, то есть '['Alice', 'Bob', 'Carl']', вам может понадобиться использовать 'rangePoints' вместо' range'. –

+0

Не могли бы вы объяснить это без слов, таких как «дискретный домен», «количественный масштаб», «интерполированный», «принудительный» и «домен», чтобы мы могли смиренно землян понять это? Или, по крайней мере, определить их. Не у всех нас есть математический фон. – dthree

2

В шкалах D3.js преобразование числа из домена в диапазон. Для линейного масштаба область будет непрерывной переменной с неограниченным диапазоном значений, которая затем может быть преобразована в непрерывный диапазон. Для порядковых шкал будет дискретная область, например месяцы года, где имеется ограниченный диапазон возможных значений, которые могут быть упорядочены, но не являются непрерывными. API docs on Github, вероятно, может объяснить разницу лучше, чем у меня есть

0

ОК, мы можем начать изучение с использованием как с теми же данными, чтобы увидеть различия (я использую d3 v4), представьте себе, у нас есть данные ниже с использованием ordinal и linear весы:

const data = [1, 2, 3, 4, 5]; 

const scaleLinear = d3.scaleLinear() 
    .domain([0, Math.max(...data)]).range([1, 100]); 

const scaleOrdinal = d3.scaleOrdinal() 
    .domain(data).range(['one', 'two', 'three', 'four', 'five']); 

Теперь мы начинаем называть их, чтобы увидеть результат:

scaleLinear(1); //20 
scaleOrdinal(1); //one 

scaleLinear(2); //40 
scaleOrdinal(2); //two 

scaleLinear(5); //100 
scaleOrdinal(5); //five 

Посмотрите на функции и результаты, которые мы получаем, как вы видите в порядковых один отобразят данные в наш диапазон, в то время как в линейных мы растянуть диапазон, поэтому в этих случаях, например, scaleLinear (1) возвратит 20 ... наш домен не более 100 и 100 разделить на 5 равно 20, так scaleLinear (1) является и scaleLinear (2) является .. .

Но, как вы видите, scaleOrdinal (1) является карта для массива в диапазоне, поэтому он равен один и scaleOrdinal (2) он равен два ...

Так что, как вы можете использовать эти весы, scaleLinear полезно для многих вещей, в том числе присутствует масштаб на странице, но scaleOrdinal более полезный для получения данных для того, что, как это описано в документации:

# d3.scaleLinear() <>

Создает новую непрерывную шкалу с единичной областью [0, 1], диапазон блока [0, 1], интерполятор по умолчанию и зажим отключен. Линейные весы являются хорошим выбором по умолчанию для непрерывных количественных данных , поскольку они сохраняют пропорциональные различия. Каждое значение диапазона y может быть выражено как функция значения домена x: y = mx + b.


d3.scaleOrdinal ([диапазон]) <>

Создает новый порядковый масштаб с пустой области и указанного диапазона. Если диапазон не указан, по умолчанию используется пустой массив; порядковый масштаб всегда возвращается неопределенным до тех пор, пока не будет определен пустой пробел .

Кроме того, это хороший пример из d3 в глубину с использованием как порядковые и линейных весов в то же время:

var myData = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] 
 

 
var linearScale = d3.scaleLinear() 
 
    .domain([0, 11]) 
 
    .range([0, 600]); 
 

 
var ordinalScale = d3.scaleOrdinal() 
 
    .domain(myData) 
 
    .range(['black', '#ccc', '#ccc']); 
 

 
d3.select('#wrapper') 
 
    .selectAll('text') 
 
    .data(myData) 
 
    .enter() 
 
    .append('text') 
 
    .attr('x', function(d, i) { 
 
    return linearScale(i); 
 
    }) 
 
    .text(function(d) { 
 
    return d; 
 
    }) 
 
    .style('fill', function(d) { 
 
    return ordinalScale(d); 
 
    });
body { 
 
    font-family: "Helvetica Neue", Helvetica, sans-serif; 
 
    font-size: 14px; 
 
    color: #333; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.min.js"></script> 
 

 
<svg width="800" height="60"> 
 
    \t <g id="wrapper" transform="translate(100, 40)"> 
 
    \t </g> 
 
</svg>

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