Используйте возможности D3.js для создания красивых представлений ваших данных.
D3.js - это библиотека JavaScript с открытым исходным кодом, используемая для создания красивых представлений данных, которые мы можем просматривать в любом современном браузере. Используя D3.js, мы можем создавать различные виды диаграмм и графиков из наших данных.
В этом уроке мы собираемся создать линейную диаграмму, отображающую индекс цен на биткойны за последние шесть месяцев. Мы будем извлекать данные из внешнего API и визуализировать линейную диаграмму с метками и осью внутри DOM.
Мы также создали бесплатный курс D3.js по Scrimba. Посмотрите здесь.
Начиная
Прежде всего, мы импортируем библиотеку D3.js прямо из CDN внутри нашего HTML.
<html> <head> <link rel="stylesheet" href="index.css"> </head> <body> <svg></svg> <script src="https://d3js.org/d3.v4.min.js"></script> </body> </html>
Мы также добавили тег <svg></svg>
в наш HTML-код, чтобы создать внутри него линейную диаграмму с помощью D3.js.
Теперь перейдем к написанию нашего кода JavaScript. Прежде всего, мы хотим загрузить наши данные индекса цен на биткойны из внешнего API после загрузки DOM.
Получить данные
var api = 'https://api.coindesk.com/v1/bpi/historical/close.json?start=2017-12-31&end=2018-04-01'; document.addEventListener("DOMContentLoaded", function(event) { fetch(api) .then(function(response) { return response.json(); }) .then(function(data) { //DO SOMETHING WITH DATA }) });
В приведенном выше коде мы используем метод fetch
для получения данных из внешнего API. Затем мы анализируем его с помощью метода .json()
.
Теперь мы хотим преобразовать эти данные в пары ключ / значение, чтобы они были в формате date:price
. Для этого мы собираемся отправить наши данные в другую функцию, которая проанализирует и вернет их в желаемой форме.
Анализировать данные
.... .then(function(data) { var parsedData = parseData(data) }) function parseData(data) { var arr = []; for (var i in data.bpi) { arr.push( { date: new Date(i), //date value: +data.bpi[i] //convert string to number }); } return arr; }
Мы передаем наши данные функции parseData
, которая возвращает другой массив объектов. Каждый объект содержит дату и цену биткойна на эту конкретную дату.
Как только у нас будут данные в требуемом формате, мы отправим эти данные в функцию drawChart
, в которой весь оставшийся код будет записан с использованием D3.js для визуализации линейной диаграммы.
.... .then(function(data) { var parsedData = parseData(data); drawChart(parsedData); })
Выберите элемент SVG
В функции drawChart
мы в первую очередь выбираем наш элемент SVG и придаем ему некоторый стиль.
function drawChart(data) { var svgWidth = 600, svgHeight = 400; var margin = { top: 20, right: 20, bottom: 30, left: 50 }; var width = svgWidth - margin.left - margin.right; var height = svgHeight - margin.top - margin.bottom; var svg = d3.select('svg') .attr("width", svgWidth) .attr("height", svgHeight); ...
В приведенном выше коде мы устанавливаем ширину и высоту контейнера SVG, сначала выбирая его с помощью метода select()
, а затем используя метод attr()
для назначения атрибутов.
Мы также определили поля и используем их значения при вычислении атрибутов ширины и высоты контейнера SVG. Эти значения маржи помогут нам в дальнейшем правильно позиционировать и отображать нашу диаграмму.
Используя CSS, мы задали границы нашему контейнеру SVG:
<style> .line-chart { border: 1px solid lightgray; } </style>
Пока что внутри нашего DOM ничего нет:
Далее мы собираемся создать групповой элемент, который будет содержать нашу линейную диаграмму, ось и метки.
Создание и преобразование элемента группы
... var g = svg.append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")" );
Группирование элементов помогает организовать похожие или связанные элементы вместе. Здесь, после рендеринга группового элемента, мы обеспечиваем его некоторую трансформацию.
D3 дает нам различные варианты трансформации наших элементов. В приведенном выше коде мы используем свойство translate
для изменения положения нашего элемента группы с полями слева и сверху.
Добавить весы
Теперь мы хотим добавить шкалу к нашей диаграмме.
var x = d3.scaleTime().rangeRound([0, width]); var y = d3.scaleLinear().rangeRound([height, 0]);
Как мы знаем, наши данные состоят из дат и стоимости биткойнов на эти даты. Следовательно, мы можем предположить, что ось x будет содержать даты, а ось y будет содержать значения. Вот как мы можем увидеть изменение графика во времени.
Итак, в приведенном выше фрагменте кода мы создали шкалу типа времени по оси x и линейного типа по оси y. Мы также предоставляем эти шкалы с диапазонами в соответствии с шириной и высотой нашего контейнера SVG.
Создать линию
Теперь перейдем к определению нашей линии с помощью метода d3.line
. Мы будем определять атрибуты x и y строки, передавая анонимные функции и возвращая объект даты и значение биткойна для этого конкретного дня.
var line = d3.line() .x(function(d) { return x(d.date)}) .y(function(d) { return y(d.value)}) x.domain(d3.extent(data, function(d) { return d.date })); y.domain(d3.extent(data, function(d) { return d.value }));
Добавить оси
Теперь мы собираемся добавить наши левую и нижнюю оси внутри элемента группы для линейного графика. Левая ось будет представлять стоимость биткойнов, а нижняя ось отображает соответствующую дату.
g.append("g") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)) .select(".domain") .remove();
В приведенном выше коде мы добавляем элемент группы внутри нашей основной группы и переводим его в самый низ нашего контейнера. Затем мы передаем метод d3.axisBottom
в функцию вызова, где d3.axisBottom
принимает параметр x
, который определен в разделе Добавить масштаб.
g.append("g") .call(d3.axisLeft(y)) .append("text") .attr("fill", "#000") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", "0.71em") .attr("text-anchor", "end") .text("Price ($)");
Подобно нижней оси, мы добавляем еще один элемент группы, а затем вызываем для него метод d3.axisLeft
, который принимает параметр y
. Затем мы также стилизуем нашу ось, назначая ей разные атрибуты и метку.
Если мы сохраним и обновим страницу, мы увидим, что наши оси отображаются внутри DOM:
Добавить путь
На последнем шаге мы добавим путь внутри основного элемента группы. Этот путь фактически будет рисовать линейную диаграмму в соответствии со значениями данных.
Мы передаем наш набор данных с помощью метода datum
, а затем устанавливаем атрибуты цвета заливки, цвета обводки и ширины. В конце мы устанавливаем атрибут d
, который фактически дает инструкции пути SVG о том, где соединить точки пути.
g.append("path") .datum(data) .attr("fill", "none") .attr("stroke", "steelblue") .attr("stroke-linejoin", "round") .attr("stroke-linecap", "round") .attr("stroke-width", 1.5) .attr("d", line);
Вот окончательный результат:
Заключение
Поздравляю! Мы успешно создали линейный график с помощью D3.js. Вы можете проверить официальную документацию D3.js, чтобы узнать больше о различных диаграммах и графиках, которые вы можете создавать.
Если вы хотите узнать больше о D3.js, обязательно посетите наш бесплатный курс по Scrimba.
Я Сохаиб Нехал. Я разработчик веб-приложений полного стека. Вы можете связаться со мной по адресу [email protected] или в Twitter @Sohaib_Nehal. Спасибо :-)