D3 невероятно гибок в использовании входных данных. Эта глава знакомит читателя со структурами данных, которые обычно используются в JavaScript и D3.
Переменная - это самый маленький строительный блок данных, которая хранит какое-то значение. Переменная является основой для других структур данных, которые представляют собой просто различные конфигурации переменных.
Если вы новичок в JavaScript - знайте, что это слабо типизированный язык, что означает, что вы не должны указывать тип информации, которая будет храниться в переменной Многие другие языки, такие как Java(который полностью непохож на JavaScript!), требуют, чтобы вы указывали тип переменной, например int, float, boolean или String.
//Declaring variables in Java int number = 5; float value = 12.3467; boolean active = true; String text = "Crystal clear";
JavaScript, однако, актоматически определяет тип переменной, основываясь на типе информации, с которой вы связали переменную.(Обратите внимание, что '' или "" являются строковыми значениями. Я предпочитаю двойные кавычки, хотя некоторые используют одинарные.)
//Declaring variables in JavaScript var number = 5; var value = 12.3467; var active = true; var text = "Crystal clear";
Как скучно, var, var, var, var! - более удобно, когда мы объявляем и задаем имя переменной даже не зная, с каким типом данных мы ее свяжем. Вы даже можете менять тип переменных на лету, и JavaScript ничего не будет иметь против.
var value = 100; value = 99.9999; value = false; value = "This can't possibly work."; value = "Argh, it does work! No errorzzzz!";
Массив - это последовательность значений, которая удобно хранится в одной переменной.
Отслеживание связанных значений в отдельных переменных неэффективно:
var numberA = 5; var numberB = 10; var numberC = 15; var numberD = 20; var numberE = 25;
Переписать эти значения в виде массива куда проще. Квадратные скобки [] указывают на массив, в то время как каждое значение отделяется запятой:
var numbers = [ 5, 10, 15, 20, 25 ];
Массивы вездесущи в визуализации данных, поэтому вы должны очень хорошо быть с ними знакомы. Вы можете получить доступ к значению элемента массива с помощью квадратных скобок:
numbers[2] //Returns 15
Числовое значение в квадратных скобках ссылается на соответствующую позицию в массиве. Запомните, что позиции в массиве отсчитываются с нуля, поэтому первая позиция имеет индекс 0, вторая позиция - 1, и так далее.
numbers[0] //Returns 5 numbers[1] //Returns 10 numbers[2] //Returns 15 numbers[3] //Returns 20 numbers[4] //Returns 25
Некоторые люди считают, что полезно представить массив в виде таблицы со строками с столбцами, например:
ID | Value ------------ 0 | 5 1 | 10 2 | 15 3 | 20 4 | 25
Массивы могут хранить любые типы данных, не только целочисленные значения.
var percentages = [ 0.55, 0.32, 0.91 ]; var names = [ "Ernie", "Bert", "Oscar" ]; percentages[1] //Returns 0.32 names[1] //Returns "Bert"
Визуализация данных на основе программного кода была бы невозможна без использования массивов и могучего цикла for(). Вместе они образуют динамичный дуэт обработки данных.
Массив организует разные значения в одном подходящем месте. Потом цикл for() быстро пробегается по всем значениям в массиве и выполняет некоторые действия с ними - например, выражать значение в качестве наглядной формы. D3 часто организует за нас выполнение цикла благодаря методу data(), но важно уметь самим писать циклы. Я не буду вдаваться в подробности работы цикла for() здесь; это отельная история. Но обратите внимание на пример, который перебирает значения чисел, указанные сверху.
for (var i = 0; i < numbers.length; i++) { console.log(numbers[i]); //Print value to console }
Видите numbers.length? Это классная штука. Если значений в массиве 10 - значит цикл выполнится 10 раз. Если в цикле будет миллион значений, то и цикл выполнится миллион раз. Это тот случай, когда использование компьютеров является классным решением: принимая набор инструкций, выполнять их снова и снова. И именно поэтому визуализация данных может быть столь полезна - вы проектируете и программируете визуализацию данных, а система будет реагировать соответствующим образом, даже если вы будете использовать разные наборы данных. Правила преобразования данных в визуальные образы являются последовательными, даже, когда данные имеют разные форматы.
Массивы являются замечательным решением для простых наборов данных, но для более сложных наборов данных лучше бы использовать объекты. Для наших целей будем считать объекты JavaScript пользовательскими структурами данных. Мы используем фигурные скобки {} для указания объекта. В квадратные скобки мы включаем поля и их значения. Двоеточие отделяет каждое поле от его значения, а запятая отделяет каждую пару поле/значение.
var fruit = { kind: "grape", color: "red", quantity: 12, tasty: true };
Для доступа к значению поля в объекте мы используем точку, например:
fruit.kind //Returns "grape" fruit.color //Returns "red" fruit.quantity //Returns 12 fruit.tasty //Returns true
Думайте, что значения принадлежат объекту. Давайте посмотрим, что за фрукт. Вы должны задать вопрос: "Какого вида этот фрукт?". Как оказалось, fruit.kind равен "grape". На вопрос "Вкусен ли фрукт?" мы в поле fruit.tasty указываем ответ true.
Вы можете совмещать эти две структуры чтобы создавать массивы объектов, или объекты с массивами, или объекты объектов, или...любую структуру, которая возможна для вашего набора данных.
Допустим, мы приобрели еще несколько фруктов, и теперь мы хотим расширить наш набор фруктов. Мы используем квадратные скобки [] снаружи, чтобы обозначить массив, дальше мы используем фигурные скобки {}, для определения объектов:
var fruits = [ { kind: "grape", color: "red", quantity: 12, tasty: true }, { kind: "kiwi", color: "brown", quantity: 98, tasty: true }, { kind: "banana", color: "yellow", quantity: 0, tasty: true } ];
Для доступа к этим данным, мы просто берем индекс того объекта, который нам нужен. Запомните: {} обозначают объект, [] обозначают массив. fruits является массивом, поэтому мы первоначально указываем индекс в массиве:
fruit[1]
Далее, так как элементами массива являются объекты, доступ к необходимому полю предоставляется через точку:
fruit[1].quantity //Returns 98
Ниже приведена карта доступа к значениям, расположенным в объектах, хранящихся в массиве fruits:
fruits[0].kind == "grape" fruits[0].color == "red" fruits[0].quantity == 12 fruits[0].tasty == true fruits[1].kind == "kiwi" fruits[1].color == "brown" fruits[1].quantity == 98 fruits[1].tasty == true fruits[2].kind == "banana" fruits[2].color == "yellow" fruits[2].quantity == 0 fruits[2].tasty == true
Да, это так. Мы имеем в поле fruits[2].quantity 0 бананов.
Когда-нибудь в своей карьере при разработке на D3 вы столкнетесь с нотацией объектов JavaScript. Можете прочесть детали тут, но если кратко, то JSON - это синтаксис организации данных в виде объектов JavaScript. Синтаксис преимущественно оптимизирован для работы с JavaScript(что очевидно) и выполнения AJAX-запросов, поэтому вы увидите множество веб-интерфейсов, которые выплевывают данные в формате JSON. Его проще и быстрее обрабатывать нежели XML, и конечно же, D3 превосходно с ним работает.
Итак, надпись ниже теперь не выглядит более странной, чем то, что мы уже видели:
var jsonFruit = { "kind": "grape", "color": "red", "quantity": 12, "tasty": true };
Разница лишь в том, что наши поля теперь заключены в двойные кавычки, что делает их строковыми значениями.
Так же как и JSON является синтаксисом для описания объектов JavaScript, GeoJSON является оптимизированной версией JSON для хранения геоданных. Все объекты GeoJSON являются JSON объектами, а все JSON-объекты являются JavaScript объектами.
GeoJSON может хранить географические координаты, а также сложные фигуры( такие как полигоны и линии) и другие пространственные характеристики. Если у вас много геоданных, оно стоит того, чтобы заморочиться и представить их в формате GeoJSON для удобного использования с D3.
Мы еще углубимся в детали GeoJSON когда будем говорить о геокартах, а сейчас, просто посмотрите, как могут быть представлены данные в формате GeoJSON:
var geodata = { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [ 150.1282427, -24.471803 ] }, "properties": { "type": "town" } } ] };
(Заметьте, что сначала в координатах указываем долготу, а потом широту. Привыкайте.)