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

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

Верно, мы будем строить радиолокационные диаграммы для анализа данных о Бульбазавре, Чармандере и Сквиртле, чтобы раз и навсегда определить, что является лучшим выбором.

Создание радарной диаграммы на JavaScript

Для построения наших радарных диаграмм мы будем использовать библиотеку диаграмм. Библиотеки диаграмм снимают большую часть бремени построения диаграмм (по сравнению с чем-то вроде d3.js) и позволяют быстро и легко создавать диаграммы. Для этого урока я выбрал библиотеку AnyChart JavaScript. Я выбрал AnyChart, потому что с его помощью можно очень быстро создавать диаграммы, и это отличная библиотека для новичков из-за довольно объемной документации.

Шаг 1. Настройте страницу

Первым шагом для создания наших радарных диаграмм является настройка html-страницы и загрузка необходимых скриптов.

<html>
  <head>
    <script src="https://cdn.anychart.com/releases/8.7.1/js/anychart-core.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.7.1/js/anychart-radar.min.js"></script>
    <style type="text/css">
      html, body, #container {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>
  </head>
  <body>
    <div id="container"></div>
    <script>
      anychart.onDocumentReady(function () {
        // drawing our chart goes here
      });
    </script>
  </body>
</html>

Все, что я здесь сделал, - это создал новую html-страницу, добавил скрипты, необходимые для создания радарной диаграммы anychart-core.min.js и anychart-radar.min.js. Первый необходим для всех диаграмм AnyChart и поставляется с основными диаграммами (разброс, столбец и т. Д.), А второй дает нам модуль, необходимый для построения радарной диаграммы.

Затем мы создаем правило CSS для нашей html-страницы, которое устанавливает размер нашей диаграммы. Мы выбрали 100% ширину и высоту и 0 полей, чтобы создать полноэкранный вид данных, но если вы хотите чего-то другого, измените эти значения на то, что лучше соответствует вашим потребностям.

Наконец, мы используем anychart.onDocumentReady(). Наша диаграмма войдет в эту функцию. Это вызывает функцию только тогда, когда документ готов, а не раньше.

Шаг 2. Загрузите данные

Чтобы нарисовать радарные диаграммы для нашего стартового покемона, нам нужно получить данные. Я нашел это на Bulbapedia.bulbagarden.net (как мило?), Где, кажется, есть статистика для каждого покемона!

Затем нам нужно переформатировать эти данные во что-то, что AnyChart умеет читать. AnyChart любит данные для каждого наблюдения в следующем формате:

var data1 = [
  {x: "HP", value: 39},
  {x: "Attack", value: 52},
  {x: "Defense", value: 43},
  {x: "Special Attack", value: 60},
  {x: "Special Defense", value: 50},
  {x: "Speed", value: 65},
];

Массив объектов с каждой переменной, имеющей переменную оси x, которая будет называться «x», а переменная оси y будет называться «значение». В случае радиолокационной диаграммы переменная оси X - это имя переменной, а переменная оси Y - значение.

Мы повторяем этот шаг для каждого стартового покемона, в результате чего получаем следующие три массива:

var data1 = [
  {x: "HP", value: 39},
  {x: "Attack", value: 52},
  {x: "Defense", value: 43},
  {x: "Special Attack", value: 60},
  {x: "Special Defense", value: 50},
  {x: "Speed", value: 65},
];
 
var data2 = [
  {x: "HP", value: 45},
  {x: "Attack", value: 49},
  {x: "Defense", value: 49},
  {x: "Special Attack", value: 65},
  {x: "Special Defense", value: 65},
  {x: "Speed", value: 45},
]; 
 
var data3 = [
  {x: "HP", value: 44},
  {x: "Attack", value: 48},
  {x: "Defense", value: 65},
  {x: "Special Attack", value: 50},
  {x: "Special Defense", value: 64},
  {x: "Speed", value: 43},
];

Шаг 3: Рисование диаграммы

Теперь, когда у нас есть все наши (пси) утки в ряд, пора нарисовать нашу диаграмму.

// create radar chart
var chart = anychart.radar();
// set chart title
chart.title("Starter Pokemon Comparison Chart");
// set chart yScale settings
chart.yScale()
  .minimum(0)
  .maximum(100)
  .ticks({'interval':20});
// create first series
chart.line(data1)
// create second series
chart.line(data2)
// create third series
chart.line(data3)
// set container id for the chart
chart.container('container');
// initiate chart drawing
chart.draw();

Что приводит к:

Это не выглядит слишком информативным, не так ли? Все разные серии выглядят одинаково. Однако мы можем легко это исправить. Если мы изменим минимальное и максимальное значения yScale, мы сможем лучше увидеть различия между нашими 3 сериями. Затем я установил максимальное значение на 65 и минимальное значение на 35, я выбрал эти значения на основе данных, которые я пытаюсь визуализировать. Если бы у одного из наших покемонов была переменная со значением выше 65 или ниже 35, я бы выбрал другие значения, чтобы учесть это.

// set chart yScale settings
chart.yScale()
  .minimum(35)
  .maximum(65)
  .ticks({'interval':5});

Что приводит к следующему:

Ссылка на CodePen
Ссылка на площадку

<html>
  <head>
    <script src="https://cdn.anychart.com/releases/8.7.1/js/anychart-core.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.7.1/js/anychart-radar.min.js"></script>
    <style type="text/css">
      html, body, #container {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>
  </head>
  <body>
    <div id="container"></div>
  </body>
  <script>
    anychart.onDocumentReady(function () {
    // our data from bulbapedia
      var data1 = [
        {x: "HP", value: 39},
        {x: "Attack", value: 52},
        {x: "Defense", value: 43},
        {x: "Special Attack", value: 60},
        {x: "Special Defense", value: 50},
        {x: "Speed", value: 65},
      ];
      var data2 = [
        {x: "HP", value: 45},
        {x: "Attack", value: 49},
        {x: "Defense", value: 49},
        {x: "Special Attack", value: 65},
        {x: "Special Defense", value: 65},
        {x: "Speed", value: 45},
      ];
      var data3 = [
        {x: "HP", value: 44},
        {x: "Attack", value: 48},
        {x: "Defense", value: 65},
        {x: "Special Attack", value: 50},
        {x: "Special Defense", value: 64},
        {x: "Speed", value: 43},
      ];
      // create radar chart
      var chart = anychart.radar();
      // set chart yScale settings
      chart.yScale()
        .minimum(35)
        .maximum(65)
        .ticks({'interval':5});
      // create first series
      chart.line(data1)
      // create second series
      chart.line(data2)
      // create third series
      chart.line(data3)
      // set chart title
      chart.title("Starter Pokemon Comparison Chart");
      // set container id for the chart
      chart.container('container');
      // initiate chart drawing
      chart.draw();
    });
  </script>
</html>

Лучше. Теперь мы можем различать наши серии.

Шаг 4: настройка диаграммы

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

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

Цвет ячейки

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

// color alternating cells
chart.yGrid().palette(["gray 0.1", "gray 0.2"]);

Ссылка на CodePen
Ссылка на площадку

Этот код окрашивает ячейки радара в серый цвет, а чередующиеся ячейки имеют разную непрозрачность *.

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

Площадь, заливка, обводка и легенда

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

// create first series
chart.area(data1).name('Charmander').markers(true).fill("#E55934", 0.3).stroke("#E55934")
// create second series
chart.area(data2).name('Bulbasaur').markers(true).fill("#9BC53D", 0.3).stroke("#9BC53D")
// create third series
chart.area(data3).name('Squirtle').markers(true).fill("#5BC0EB", 0.3).stroke("#5BC0EB")

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

// set chart title
chart.title("Starter Pokemon Comparison Chart");
  // set legend
  .legend(true);

Ссылка на CodePen
Ссылка на площадку

Переупорядочить переменные

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

В нашем примере мы бы изменили это:

var data1 = [
  {x: "HP", value: 39},
  {x: "Attack", value: 52},
  {x: "Defense", value: 43},
  {x: "Special Attack", value: 60},
  {x: "Special Defense", value: 50},
  {x: "Speed", value: 65},
];

К этому

var data1 = [
  {x: "Speed", value: 65},
  {x: "HP", value: 39},
  {x: "Defense", value: 43},
  {x: "Special Defense", value: 50},
  {x: "Special Attack", value: 60},
  {x: "Attack", value: 52},
];

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

Ссылка на CodePen
Ссылка на площадку

<html>
  <head>
    <script src="https://cdn.anychart.com/releases/8.7.1/js/anychart-core.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.7.1/js/anychart-radar.min.js"></script>
    <style type="text/css">
      html, body, #container {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>
  </head>
  <body>
    <div id="container"></div>
  </body>
  <script>
    anychart.onDocumentReady(function () {
      
// our data from bulbapedia
var data1 = [
  {x: "Speed", value: 65},
  {x: "HP", value: 39},
  {x: "Defense", value: 43},
  {x: "Special Defense", value: 50},
  {x: "Special Attack", value: 60},
  {x: "Attack", value: 52}
];
var data2 = [
  {x: "Speed", value: 45},
  {x: "HP", value: 45},
  {x: "Defense", value: 49},
  {x: "Special Defense", value: 65},
  {x: "Special Attack", value: 65},
  {x: "Attack", value: 49}
];
var data3 = [
  {x: "Speed", value: 43},
  {x: "HP", value: 44},
  {x: "Defense", value: 65},
  {x: "Special Defense", value: 64},
  {x: "Special Attack", value: 50},
  {x: "Attack", value: 48}
];
// create radar chart
var chart = anychart.radar();
// set chart yScale settings
chart.yScale()
  .minimum(35)
  .maximum(65)
  .ticks({'interval':5});
// color alternating cells
chart.yGrid().palette(["gray 0.1", "gray 0.2"]);
// create first series
chart.area(data1).name('Charmander').markers(true).fill("#E55934", 0.3).stroke("#E55934")
// create second series
chart.area(data2).name('Bulbasaur').markers(true).fill("#9BC53D", 0.3).stroke("#9BC53D")
// create third series
chart.area(data3).name('Squirtle').markers(true).fill("#5BC0EB", 0.3).stroke("#5BC0EB")
// set chart title
chart.title("Starter Pokemon Comparison Chart")
  // set legend
        .legend(true);
// set container id for the chart
chart.container('container');
// initiate chart drawing
chart.draw();
    });
  </script>
</html>

Мы можем ясно видеть, что Чармандер более атакующий, Сквиртл более оборонительный, а Бульбазавр более округлый. И поэтому я бы сказал, что, используя эту таблицу (и я понимаю, насколько это антиклиматический вывод), мы можем ясно увидеть, что все покемоны - правильный выбор. Все они довольно хорошо сбалансированы и у всех есть свои сильные и слабые стороны.

Заключение

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

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

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

Первоначально опубликовано на https://www.anychart.com 7 июля 2020 г.

JavaScript на простом английском языке

Понравилась эта статья? Если да, то получите больше похожего контента, подписавшись на наш канал YouTube!