Расширенный учебник по D3.js: 5 лучших советов и приемов

Расширенный учебник по D3.js 5 лучших советов и приемов Изучение

D3.js — это инструмент визуализации данных JavaScript, который быстро набирает популярность среди разработчиков интерфейса и специалистов по данным. Многие разработчики предпочитают D3.js другим инструментам визуализации данных, поскольку он использует веб-стандарты HTML, CSS и JavaScript для управления внешним видом диаграмм и графиков. Это позволяет разработчикам интерфейса сразу перейти к анализу на основе данных без необходимости изучать новый язык программирования или технологию.

Объедините это с простой в реализации анимацией и встроенными функциями рендеринга, и станет ясно, почему так много работодателей ищут фронтенд-разработчиков с опытом работы с проектами D3.

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

1. Цепочка переходов

Переходы — один из самых любимых аспектов D3.js. Их легко реализовать, и их можно легко настроить для любого типа данных или желаемого внешнего вида. Однако знаете ли вы, что вы можете связать несколько переходов, чтобы они происходили последовательно из одного события?

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

Цепные переходы отлично подходят для демонстрации будущих эффектов или для привлечения внимания к определенным элементам во время презентации.

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

<!DOCTYPE html>
<meta charset=»utf-8″>
<body>
<!— load the d3.js library —>
<script src=»https://d3js.org/d3.v6.min.js»></script>
<script>
var svg = d3.select(«body») // Select the body element
    .append(«svg»)          // Append an SVG element to the body
    .attr(«width», 960)     // make it 960 pixels wide
    .attr(«height», 500)    // make it 500 pixels high
    .append(«circle»)       // append a circle to the svg
    .style(«fill», «blue»)  // fill the circle with ‘blue’
    .attr(«r», 20)          // set the radius to 10 pixels
    .attr(‘cx’, 40)         // position the circle at 40 on the x axis
    .attr(‘cy’, 250)        // position the circle at 250 on the y axis
    .transition()           // apply a transition
    .duration(4000)         // apply it over 4000 milliseconds
    .attr(‘cx’, 850)        // new horizontal position at 850 on x axis
    .attr(‘r’, 40)          // new radius of 40 pixels
    .style(‘fill’, «red»);  // new colour red
</script>
</body>

Этот код перехода соответствует всем нашим критериям, но не связан. Все переходы произойдут сразу.

Читайте также:  3 основные парадигмы программирования, которые вы должны знать

Чтобы переходы выполнялись по одному, нам нужно настроить наш код, чтобы он соответствовал следующему:

<!DOCTYPE html>
<meta charset=»utf-8″>
<body>
<!— load the d3.js library —>
<script src=»https://d3js.org/d3.v6.min.js»></script>
<script>
var svg = d3.select(«body») // Select the body element
    .append(«svg»)          // Append an SVG element to the body
    .attr(«width», 960)     // make it 960 pixels wide
    .attr(«height», 500)    // make it 500 pixels high
    .append(«circle»)       // append a circle to the svg
        .style(«fill», «blue»)  // fill the circle with ‘blue’
        .attr(«r», 20)          // set the radius to 10 pixels
        .attr(‘cx’, 40)         // position the circle at 40 on the x axis
        .attr(‘cy’, 250)        // position the circle at 250 on the y axis
    // 1st transition
        .transition()           // apply a transition
        .duration(4000)         // apply it over 4000 milliseconds
        .attr(‘cx’, 830)        // new horizontal position at 830 on x axis
    // 2nd transition
        .transition()           // apply a transition
        .duration(4000)         // apply it over 4000 milliseconds
        .attr(‘r’, 40)          // new radius of 40 pixels
    // 3rd transition
        .transition()           // apply a transition
        .duration(4000)         // apply it over 4000 milliseconds
        .style(‘fill’, «red»);  // new colour red
</script>
</body>

Теперь наш переход выполняется в три отдельных этапа:

Теперь наш переход выполняется в три отдельных этапа

2. Добавление веб-ссылок к объекту D3.js

Один график редко может рассказать всю историю. Иногда полезно включать в элементы переходные ссылки, которые могут привести пользователя к более глубокому изучению конкретной темы. Веб-ссылки лучше всего использовать, чтобы позволить пользователям естественным образом исследовать данные или предоставить доступ к дополнительным ресурсам, которые могут помочь им понять ваш график.

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

Для этого нам понадобится <a>тег и xlinkключевое слово. <a>Тег в HTML — файл определяет гиперссылку. Элементы, окруженные <a>тегом, станут ссылкой на другой веб-адрес. Итак, что мы сделаем, так это создадим <a>тег, а затем добавим к нему наш D3.js и объект SVG.

Конечно, помимо ссылки, мы должны указать ей, куда идти. Мы делаем это, устанавливая xlink:hrefатрибут для нашего тега, указывающий на конкретную страницу. Xlink- это сокращение от XML Linking Language, и он используется для создания гиперссылок в XML-документах. В нашем случае мы будем определять ссылку, по которой должен переходить наш пользователь.

Вместо того, чтобы связывать текст и прямоугольник со ссылкой, мы заставим программу игнорировать текст и взаимодействовать только с элементом прямоугольника. Мы можем сделать это, используя pointer-eventsстиль при рисовании нашего текста. Устанавливая его на none, мы даем указание нашей мыши игнорировать любое возможное взаимодействие с текстом при наведении на него курсора, и вместо этого указатель зарегистрирует ссылку в прямоугольнике под ним.

<!DOCTYPE html>
<meta charset=»utf-8″>
<body>
<!— load the d3.js library —>
<script src=»https://d3js.org/d3.v6.min.js»></script>
<script>
var width = 449;
var height = 249;
var word = «frontend»;
var holder = d3.select(«body»)
      .append(«svg»)
      .attr(«width», width)
      .attr(«height», height);
// draw a rectangle
holder.append(«a»)
    .attr(«xlink:href», «http://en.wikipedia.org/wiki/»+word)
    .append(«rect»)
    .attr(«x», 100)
    .attr(«y», 50)
    .attr(«height», 100)
    .attr(«width», 200)
    .style(«fill», «lightgreen»)
    .attr(«rx», 10)
    .attr(«ry», 10);
// draw text on the screen
holder.append(«text»)
    .attr(«x», 200)
    .attr(«y», 100)
    .style(«fill», «black»)
    .style(«font-size», «20px»)
    .attr(«dy», «.35em»)
    .attr(«text-anchor», «middle»)
    .style(«pointer-events», «none»)
    .text(word);
</script>
</body>

Функциональный элемент «frontend» со ссылкой

Функциональный элемент frontend со ссылкой

3. Включение HTML-таблиц в ваш график

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

Таблицы HTML состоят из строк, столбцов и данных, содержащихся в каждой ячейке. Все, что вам нужно сделать, чтобы успешно разместить таблицу на веб-странице, — это расположить строки и столбцы в логической последовательности, используя соответствующие теги HTML.

Например, взгляните на HTML-код ниже, чтобы увидеть простую реализацию таблицы:

HTML:

<!DOCTYPE html>
<body>
    <table border="1">
        <tr>
            <th>Header 1</th>
            <th>Header 2</th>
        </tr>
        <tr>
            <td>row 1, cell 1</td>
            <td>row 1, cell 2</td>
        </tr>
        <tr>
            <td>row 2, cell 1</td>
            <td>row 2, cell 2</td>
        </tr>
    </table>
</body>

Результат:

Сама таблица заключена в table теги

Сама таблица заключена в <table>теги. Каждая строка заключена в <tr>теги. В каждой строке есть два элемента, которые соответствуют двум столбцам. Каждый фрагмент данных для каждой ячейки заключен в <td>тег, за исключением первой строки, которая является заголовком. Заголовок имеет специальный тег, <th>который выделяет его жирным шрифтом и выравнивает его по центру.

Для простоты просмотра мы приказали таблице разместить границу вокруг каждой ячейки, и мы делаем это в первом <table>теге с border=»1″оператором.

Теперь давайте добавим таблицу HTML под графиком D3. Строки 77-114 создают нашу таблицу.

index.html

<!DOCTYPE html>
<meta charset=»utf-8″>
<style> /* set the CSS */
.line {
  fill: none;
  stroke: steelblue;
  stroke-width: 2px;
}
td, th {
    padding: 1px 4px;
}
</style>
<body>
<!— load the d3.js library —>
<script src=»https://d3js.org/d3.v6.min.js»></script>
<script>
// set the dimensions and margins of the graph
var margin = {top: 20, right: 20, bottom: 30, left: 50},
    width = 960 — margin.left — margin.right,
    height = 500 — margin.top — margin.bottom;
// parse the date / time
var parseTime = d3.timeParse(«%d-%b-%y»);
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
// define the line
var valueline = d3.line()
    .x(function(d) { return x(d.date1); })
    .y(function(d) { return y(d.close); });
// append the svg obgect to the body of the page
// appends a ‘group’ element to ‘svg’
// moves the ‘group’ element to the top left margin
var svg = d3.select(«body»).append(«svg»)
    .attr(«width», width + margin.left + margin.right)
    .attr(«height», height + margin.top + margin.bottom)
  .append(«g»)
    .attr(«transform»,
          «translate(» + margin.left + «,» + margin.top + «)»);
// Get the data
d3.csv(«data.csv»).then(function(data) {
  // format the data
  data.forEach(function(d) {
      d.date1 = parseTime(d.date);
      d.close = +d.close;
  });
  // Scale the range of the data
  x.domain(d3.extent(data, function(d) { return d.date1; }));
  y.domain([0, d3.max(data, function(d) { return d.close; })]);
  // Add the valueline path.
  svg.append(«path»)
      .data([data])
      .attr(«class», «line»)
      .attr(«d», valueline);
  // Add the X Axis
  svg.append(«g»)
      .attr(«transform», «translate(0,» + height + «)»)
      .call(d3.axisBottom(x));
  // Add the Y Axis
  svg.append(«g»)
      .call(d3.axisLeft(y));
// The table generation function
function tabulate(data, columns) {
    var table = d3.select(«body»).append(«table»)
            .attr(«style», «margin-left: 400px»),
        thead = table.append(«thead»),
        tbody = table.append(«tbody»);
    // append the header row
    thead.append(«tr»)
        .selectAll(«th»)
        .data(columns)
        .enter()
        .append(«th»)
            .text(function(column) { return column; });
    // create a row for each object in the data
    var rows = tbody.selectAll(«tr»)
        .data(data)
        .enter()
        .append(«tr»);
    // create a cell in each row for each column
    var cells = rows.selectAll(«td»)
        .data(function(row) {
            return columns.map(function(column) {
                return {column: column, value: row[column]};
            });
        })
        .enter()
        .append(«td»)
        .attr(«style», «font-family: Courier») // sets the font style
            .html(function(d) { return d.value; });
    return table;
}
// render the table
 var peopleTable = tabulate(data, [«date», «close»]);
});
</script>
</body>

data.cvs

date,close
1-May-12,58.13
30-Apr-12,53.98
27-Apr-12,67.00
26-Apr-12,89.70
25-Apr-12,99.00
24-Apr-12,130.28
23-Apr-12,166.70
20-Apr-12,234.98
19-Apr-12,345.44
18-Apr-12,443.34
17-Apr-12,543.70
16-Apr-12,580.13
13-Apr-12,605.23
12-Apr-12,622.77
11-Apr-12,626.20
10-Apr-12,628.44
9-Apr-12,636.23
5-Apr-12,633.68
4-Apr-12,624.31
3-Apr-12,629.32
2-Apr-12,618.63
30-Mar-12,599.55
29-Mar-12,609.86
28-Mar-12,617.62
27-Mar-12,614.48
26-Mar-12,606.98

График с таблицей HTML внизу

График с таблицей HTML внизу

4. Переключение отображения / скрытия элементов графика одним щелчком мыши.

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

Один из простых способов сделать это — позволить пользователям скрыть определенные точки данных, чтобы ближе познакомиться с взаимосвязями или тенденциями. Чем больше точек данных на одном графике, тем полезнее становится эта функция!

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

Образец линейного графика

Образец линейного графика

Реализация этой техники состоит из двух основных частей. Во-первых, мы должны пометить элемент (или элементы), который мы хотим показать / скрыть, щелчком мыши. Затем мы должны дать интерактивному объекту атрибут, который позволяет ему распознавать щелчок мыши, а затем выполнить код, чтобы показать / скрыть наш помеченный элемент.

Вот как бы мы реализовали эти шаги в D3.js:

index.html

<!DOCTYPE html>
<meta charset=»utf-8″>
<style> /* set the CSS */
.line {
  fill: none;
  stroke: steelblue;
  stroke-width: 2px;
}
.axisSteelBlue text{
  fill: steelblue;
}
.axisRed text{
  fill: red;
}
.legend {
  font: 16px sans-serif;
  font-weight: bold;
  text-anchor: start;
}
</style>
<body>
<!— load the d3.js library —>
<script src=»https://d3js.org/d3.v6.min.js»></script>
<script>
// set the dimensions and margins of the graph
var margin = {top: 20, right: 40, bottom: 60, left: 50},
    width = 960 — margin.left — margin.right,
    height = 500 — margin.top — margin.bottom;
// parse the date / time
var parseTime = d3.timeParse(«%d-%b-%y»);
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y0 = d3.scaleLinear().range([height, 0]);
var y1 = d3.scaleLinear().range([height, 0]);
// define the 1st line
var valueline = d3.line()
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y0(d.close); });
// define the 2nd line
var valueline2 = d3.line()
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y1(d.open); });
// append the svg obgect to the body of the page
// appends a ‘group’ element to ‘svg’
// moves the ‘group’ element to the top left margin
var svg = d3.select(«body»).append(«svg»)
    .attr(«width», width + margin.left + margin.right)
    .attr(«height», height + margin.top + margin.bottom)
  .append(«g»)
    .attr(«transform»,
          «translate(» + margin.left + «,» + margin.top + «)»);
// get the data
d3.csv(«data4.csv»).then(function(data) {
  // format the data
  data.forEach(function(d) {
      d.date = parseTime(d.date);
      d.close = +d.close;
      d.open = +d.open;
  });
  // scale the range of the data
  x.domain(d3.extent(data, function(d) { return d.date; }));
  y0.domain([0, d3.max(data, function(d) {return Math.max(d.close);})]);
  y1.domain([0, d3.max(data, function(d) {return Math.max(d.open); })]);
  // add the valueline path.
  svg.append(«path»)
      .data([data])
      .attr(«class», «line»)
      .attr(«id», «blueLine»)
      .attr(«d», valueline);
  // add the valueline2 path.
  svg.append(«path»)
      .data([data])
      .attr(«class», «line»)
      .attr(«id», «redLine»)
      .style(«stroke», «red»)
      .attr(«d», valueline2);
  // add the X Axis
  svg.append(«g»)
      .attr(«transform», «translate(0,» + height + «)»)
      .call(d3.axisBottom(x));
  // add the Y0 Axis
  svg.append(«g»)
      .attr(«class», «axisSteelBlue»)
      .call(d3.axisLeft(y0));
  // add the Y1 Axis
  svg.append(«g»)
      .attr(«class», «axisRed»)
      .attr(«transform», «translate( » + width + «, 0 )»)
      .call(d3.axisRight(y1));
  // add the blue line legend
  svg.append(«text»)
     .attr(«x», 0)
     .attr(«y», height + margin.top + 15)
     .attr(«class», «legend»)
     .style(«fill», «steelblue»)
     .on(«click», function(){
       // determine if current line is visible
       var active   = blueLine.active ? false : true,
       newOpacity = active ? 0 : 1;
       // hide or show the elements
       d3.select(«#blueLine»).style(«opacity», newOpacity);
       // update whether or not the elements are active
       blueLine.active = active;
     })
     .text(«Blue Line»);
  // add the red line legend
  svg.append(«text»)
     .attr(«x», 0)
     .attr(«y», height + margin.top + 35)
     .attr(«class», «legend»)
     .style(«fill», «red»)
     .on(«click», function(){
       // determine if current line is visible
       var active   = redLine.active ? false : true,
       newOpacity = active ? 0 : 1;
       // hide or show the elements
       d3.select(«#redLine»).style(«opacity», newOpacity);
       // update whether or not the elements are active
       redLine.active = active;
     })
     .text(«Red Line»);
});
</script>
</body>

data4.csv

date,close,open
1-May-12,58.13,3.41
30-Apr-12,53.98,4.55
27-Apr-12,67.00,6.78
26-Apr-12,89.70,7.85
25-Apr-12,99.00,8.92
24-Apr-12,130.28,9.92
23-Apr-12,166.70,10.13
20-Apr-12,234.98,12.23
19-Apr-12,345.44,13.45
18-Apr-12,443.34,16.04
17-Apr-12,543.70,18.03
16-Apr-12,580.13,21.02
13-Apr-12,605.23,22.34
12-Apr-12,622.77,20.15
11-Apr-12,626.20,21.26
10-Apr-12,628.44,31.04
9-Apr-12,636.23,35.04
5-Apr-12,633.68,41.02
4-Apr-12,624.31,43.05
3-Apr-12,629.32,46.03
2-Apr-12,618.63,51.03
30-Mar-12,599.55,53.42
29-Mar-12,609.86,57.82
28-Mar-12,617.62,59.01
27-Mar-12,614.48,56.03
26-Mar-12,606.98,58.01

data.csv

date,close
1-May-12,58.13
30-Apr-12,53.98
27-Apr-12,67.00
26-Apr-12,89.70
25-Apr-12,99.00
24-Apr-12,130.28
23-Apr-12,166.70
20-Apr-12,234.98
19-Apr-12,345.44
18-Apr-12,443.34
17-Apr-12,543.70
16-Apr-12,580.13
13-Apr-12,605.23
12-Apr-12,622.77
11-Apr-12,626.20
10-Apr-12,628.44
9-Apr-12,636.23
5-Apr-12,633.68
4-Apr-12,624.31
3-Apr-12,629.32
2-Apr-12,618.63
30-Mar-12,599.55
29-Mar-12,609.86
28-Mar-12,617.62
27-Mar-12,614.48
26-Mar-12,606.98

В приведенном ниже объяснении рассматривается

В приведенном ниже объяснении рассматривается, как можно сделать переключаемую синюю линию.

Чтобы пометить элемент, добавьте idк элементу атрибут, который однозначно его идентифицирует. Мы будем использовать это, чтобы скрыть только один элемент, но не другие.

  • Строки 81-85 : В приведенном выше примере мы применили идентификатор blueLine (строка 84) к пути, который рисует синюю линию на нашем графике.
  • Строки 112–126 : Вторая часть немного сложнее. Ниже приведен фрагмент кода JavaScript, который помещает нашу текстовую метку под график. Единственная его часть, которая необычна, — это файл. on(«click», function()раздел кода.

Когда мы щелкаем по нашему текстовому элементу в виде синей строки,.on(«click», function()выполняется раздел.

  • Строки 119–120 : мы несколько раз использовали здесь сокращенную версию ifутверждения. Во — первых, мы проверяем, если переменная blueLine.activeявляется trueили false. Если да true, то устанавливается в false, а если да false, то устанавливается в true. Другими словами, он переворачивает логическое значение при каждом щелчке.

Затем, переключив эту переменную, мы устанавливаем значение newOpacity0 или 1, в зависимости от того, activeесть ли это trueили falseво втором сокращенном ifоператоре JavaScript.

  • Строка 122: Затем мы можем выбрать наши идентификаторы, которые мы объявили, используя idатрибуты в более ранних частях кода, и изменить их непрозрачность на 0 (выключено) или 1 (включено).
  • Строка 124 : Наконец, мы обновляем нашу blueLine.activeпеременную до любого активного состояния, чтобы она могла правильно переключаться при следующем нажатии.

5. Фильтрация с помощью if оператора

Вместо того, чтобы скрывать элементы, вы можете выделить определенные точки данных на основе определенных критериев. Это полезно при анализе больших наборов данных на предмет выбросов или данных, превышающих определенный порог, например тех, которые имеют место в определенную дату.

D3.js позволяет делать это, включая стандартные ifоператоры JavaScript во время создания графа. Например, предположим, что мы хотели создать диаграмму рассеяния, которая выделяет все точки со значением больше 300.

  // Add the scatterplot
  svg.selectAll(«dot»)
      .data(data)
    .enter().append(«circle»)
      .attr(«r», 5)
      .style(«fill», function(d) {            // <== Add these
          if (d.close <= 400) {return «red»}  // <== Add these
          else { return «black» }             // <== Add these
      ;})                                     // <== Add these
      .attr(«cx», function(d) { return x(d.date); })
      .attr(«cy», function(d) { return y(d.close); });
  • Строки 6-7 устанавливают, fillкоторые будут определены на основании значения точки данных.
  • В конце строки 7 проверяется, меньше ли значение точки данных 400, и устанавливается fillзначение redtrue.
  • Если точка данных больше 400, строка 8 выполняется и становится fillчерной.

Черный светится при значениях больше 400

Черный светится при значениях больше 400

Вы также можете установить несколько ifфильтров для дальнейшей настройки вашего графика.

  // Add the scatterplot
  svg.selectAll(«dot»)
      .data(data)
    .enter().append(«circle»)
      .attr(«r», 5)
      .style(«fill», function(d) {
         if (d.close <= 400) {return «red»}
         else if (d.close >= 620) {return «lawngreen»} // <== Right here
         else { return «black» }
      ;})
      .attr(«cx», function(d) { return x(d.date); })
      .attr(«cy», function(d) { return y(d.close); });

else-if Заявление по линии 8 комплектов дополнительный фильтр для поиска точек данных, которые больше или равны 620.

Точки больше 400 - черные, точки больше 620 - зеленые

Точки больше 400 — черные, точки больше 620 — зеленые.

Что изучать дальше

Подобные советы и уловки определяют разницу между разработчиком D3.js и мастером. Каждый из них сделает ваши графики более всеобъемлющими и интерактивными, что позволит вам лучше удовлетворять потребности ваших пользователей.

Однако есть еще много уловок D3.js, которые вы можете использовать для оптимизации своих проектов. Другие особенности D3, которые следует изучить дальше:

  • Размещение / вращение интерактивных элементов
  • Экспорт изображений
  • Реализация пользовательского ввода
  • Интеграция JSON
Оцените статью
bestprogrammer.ru
Добавить комментарий