Как перенести данные в диаграммы

Сегодня мы займемся визуализацией данных с помощью JavaScript. Для захвата и добавления данных нам потребуется Chart.js:

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js"></script>

Источник 1: таблица данных HTML

Добавьте немного JavaScript, и данные HTML-таблицы можно будет представить с помощью диаграммы. Взгляните на таблицу, приведенную ниже:

ГодПродано (шт.)Оборот ($)Доход ($)
20161020089
201725550225
2018551200600
201912024501100

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

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

function BuildChart(labels, values, chartTitle) {
  var ctx = document.getElementById("myChart").getContext('2d');
  var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
      labels: labels, // Наши метки
      datasets: [{
        label: chartTitle, // Название рядов
        data: values, // Значения
        backgroundColor: [ // Задаем произвольные цвета
          'rgba(255, 99, 132, 0.2)',
          'rgba(54, 162, 235, 0.2)',
          'rgba(255, 206, 86, 0.2)',
          'rgba(75, 192, 192, 0.2)',
          'rgba(153, 102, 255, 0.2)',
          'rgba(255, 159, 64, 0.2)'
        ],
        borderColor: [ // Добавляем произвольный цвет обводки
          'rgba(255,99,132,1)',
          'rgba(54, 162, 235, 1)',
          'rgba(255, 206, 86, 1)',
          'rgba(75, 192, 192, 1)',
          'rgba(153, 102, 255, 1)',
          'rgba(255, 159, 64, 1)'
        ],
        borderWidth: 1 // Задаем ширину обводки секций
      }]
    },
    options: {
      responsive: true, // Даем Chart.js указание реагировать правильно.
      maintainAspectRatio: false, // Добавляем эту строку, чтобы избежать переключения на полноразмерный вид (высоту/ширину) 
    }
  });
  return myChart;
}

Теперь, когда мы определились с функцией для создания диаграммы из табличных значений, переведем таблицу в HTML-код. Также добавим элемент canvas, который потребуется Chart.js для построения диаграмм. Это те же данные, что и в таблице, приведенной выше.

<table class="table" id="dataTable">
  <thead>
    <th>Год</th>
    <th>Продано (шт)</th>
    <th>Оборот ($)</th>
    <th>Прибыль ($)</th>
  </thead>
  <tbody>
    <tr>
      <td>2016</td>
      <td>10</td>
      <td>200</td>
      <td>89</td>
    </tr>
    <tr>
      <td>2017</td>
      <td>25</td>
      <td>550</td>
      <td>225</td>
    </tr>
    <tr>
      <td>2018</td>
      <td>55</td>
      <td>1200</td>
      <td>600</td>
    </tr>
    <tr>
      <td>2019</td>
      <td>120</td>
      <td>2450</td>
      <td>1100</td>
    </tr>
  </tbody>
</table>

<div class="chart">
  <canvas id="myChart"></canvas>
</div>

Затем нужно преобразовать данные таблицы в формат JSON с помощью Vanilla JS. Библиотека Chart.js использует следующую структуру для заполнения графиков и диаграмм.

var table = document.getElementById('dataTable');
var json = []]; // Первая строка – это заголовки 
var headers =[];
for (var i = 0; i < table.rows[0].cells.length; i++) {
  headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi, '');
}

// Перебор ячеек 
for (var i = 1; i < table.rows.length; i++) {
  var tableRow = table.rows[i];
  var rowData = {};
  for (var j = 0; j < tableRow.cells.length; j++) {
    rowData[headers[j]] = tableRow.cells[j].innerHTML;
  }

  json.push(rowData);
}

console.log(json);

Последнюю строку мы добавили для вывода результата в консоли DevTools. Вот, что отображается в логах консоли:

Источник 1: таблица данных HTML

Заголовки таблицы стали переменными и теперь отображаются в ячейках таблицы. Теперь осталось поместить метки годов (year) и проданных товаров (items sold) в массив. Он нужен Chart.js для хранения объектов данных и передачи данных в функцию диаграммы.

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

// Добавляем JSON-значения в массив меток
var labels = json.map(function (e) {
  return e.year;
});
console.log(labels); // ["2016", "2017", "2018", "2019"]

// Добавляем JSON-значения в массив значений
var values = json.map(function (e) {
  return e.itemssold;
});
console.log(values); // ["10", "25", "55", "120"]

Вызываем функцию BuildChart из первого фрагмента кода (включая название диаграммы). Получается красивая визуализация данных из HTML-таблицы.

var chart = BuildChart(labels, values, "Продажи товаров за период");

Данные для диаграммы переданы JavaScript и представлены в графическом виде.

Источник 2: API в режиме реального времени

Рассмотрим, как воспользоваться данными, обновляемыми в режиме реального времени, для заполнения диаграммы с использованием API. Я воспользуюсь Forbes 400 Rich List API и выведу ТОП-10 самых богатых людей на планете с помощью диаграммы.

Из API мы будем запрашивать данные для создания диаграммы с именами и актуальным доходом. Для начала нужно заново определить функцию chart.

function BuildChart(labels, values, chartTitle) {
  var data = {
    labels: labels,
    datasets: [{
      label: chartTitle, // Названия рядов
      data: values,
      backgroundColor: ['rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
      ],
    }],
  };
  var ctx = document.getElementById("myChart").getContext('2d');
  var myChart = new Chart(ctx, {
    type: 'horizontalBar',
    data: data,
    options: {
      responsive: true, // Даем Chart.JS указание реагировать правильно.
      maintainAspectRatio: false, // Добавляем эту строку, чтобы избежать стандартного переключения на полноразмерный вид (высоту/ширину) 
      scales: {
        xAxes: [{
          scaleLabel: {
            display: true,
            labelString: '$ Billion'
          }
        }],
        yAxes: [{
          scaleLabel: {
            display: true,
            labelString: 'Name'
          }
        }]
      },
    }
  });
  return myChart;
}

Далее нам потребуется тот же HTML-элемент canvas для области, в которой будет отображаться диаграмма:

<div class="chart" style="position: relative; height:80vh; width:100vw">
  <canvas id="myChart"></canvas>
</div>

Теперь выполним захват данных в режиме реального времени. Посмотрим, что возвращается в консоль после вызова Forbes API:

Источник 2: API в режиме реального времени

С помощью несложного JavaScript-кода можно запрашивать данные из API, преобразовать нужные значения. А также передавать информацию для представления в диаграмме.

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
  if (this.readyState == 4 && this.status == 200) {
    var json = JSON.parse(this.response);
    // Добавление JSON-меток(labels) в массив значений
    var labels = json.map(function (e) {
      return e.name;
    });
    // Добавление JSON-значений (values) в массив значений
    var values = json.map(function (e) {
      return (e.realTimeWorth / 1000); // Разделяем миллиардное состояние на значения, кратные десяти
    });
    BuildChart(labels, values, "Актуальные данные по состоянию знаменитостей в режиме реального времени"); // Передаем данные и вызываем chart
  }
};
xhttp.open("GET", "https://forbes400.herokuapp.com/api/forbes400?limit=10", false);
xhttp.send();

Результат

Источник 3: Google-таблица

Но что, если уже есть готовая Google-таблица с нужными данными? С ее помощью тоже можно создать диаграмму!

Основные требования к Google-таблице:

  • Она должна быть опубликована.
  • Должна быть публично доступной (не должно быть ограничений на просмотр).

При соблюдении этих условий можно обратиться к Google-таблице в формате JSON и графически представить содержащиеся в ней данные.

Вот Google-таблица с абстрактными данными. Я опубликовал ее в открытом доступе. В таблице содержится три поля: MachineId (ID машины), Date (дата) и ProductsProduced (произведено изделий).

Теперь посмотрим на URL-адрес таблицы. Нам нужна его часть после последнего слэша («/»).

https://docs.google.com/spreadsheets/d/1ySHjH6IMN0aKImYcuVHozQ_TvS6Npt4mDxpKDtsFVFg

Это идентификатор таблицы. Он понадобится для GET запроса, который отправляется в Google. Для его создания мы берем идентификатор из адреса таблицы и добавляем в другой URL.

https://spreadsheets.google.com/feeds/list/[ID GOES HERE]/od6/public/full?alt=json

Теперь URL выглядит так.

https://spreadsheets.google.com/feeds/list/1ySHjH6IMN0aKImYcuVHozQ_TvS6Npt4mDxpKDtsFVFg/od6/public/full?alt=json

А вот ответ, который мы получаем из консоли.

Источник 3: Google-таблица

Самое важное здесь – массив объектов feed.entry. Он содержит ключевую информацию из таблицы:

Источник 3: Google-таблица - 2

Обратите внимание на элементы, выделенные красным цветом. API Google-таблиц добавляет перед каждым названием столбцов gsx$ (например, gsx$date). Именно так мы и будем вытаскивать данные из объектов – с помощью уникальных сгенерированных имен. Теперь пора добавить данные в массивы и передать их в функцию chart.

function BuildChart(labels, values, chartTitle) {
  var data = {
    labels: labels,
    datasets: [{
      label: chartTitle, // Названия рядов
      data: values,
      backgroundColor: ['rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
        'rgb(54, 162, 235)',
      ],
    }],
  };

  var ctx = document.getElementById("myChart").getContext('2d');
  var myChart = new Chart(ctx, {
    type: 'bar',
    data: data,
    options: {
      responsive: true, // Даем Chart.JS указание реагировать правильно.
      maintainAspectRatio: false, // Добавляем эту строку, чтобы избежать стандартного переключения на полноразмерный вид (высоту/ширину) 
 
      scales: {
        xAxes: [{
          scaleLabel: {
            display: true,
            labelString: 'Date'
          }
        }],
        yAxes: [{
          scaleLabel: {
            display: true,
            labelString: 'Produced Count'
          }
        }]
      },
    }
  });

  return myChart;
}

Далее идет элемент canvas:

<div class="chart" style="position: relative; height:80vh; width:100vw">
  <canvas id="myChart"></canvas>
</div>

Затем – GET запрос, отображающий массивы labels и values. После чего выводим диаграмму, передавая в нее данные.

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
    var json = JSON.parse(this.response);
    console.log(json);

  // Отображение JSON-меток в массиве значений
  var labels = json.feed.entry.map(function (e) {
    return e.gsx$date.$t;
  });
      
  // Отображение JSON-значений в массиве значений
  var values = json.feed.entry.map(function (e) {
    return e.gsx$productsproduced.$t;
  });

  BuildChart(labels, values, "Данные по производству");
  }
};
xhttp.open("GET", "https://spreadsheets.google.com/feeds/list/1ySHjH6IMN0aKImYcuVHozQ_TvS6Npt4mDxpKDtsFVFg/od6/public/full?alt=json", false);
xhttp.send();

Результат

Что можно делать с данными?

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

Библиотеки для создания диаграмм:

  • Chart.js;
  • NVD3 (для D3.js);
  • amCharts;
  • CanvasJS.

Платформы для хранения данных:

  • Airtable;
  • Notion;
  • Trello.

ОСОльга Сайфудиноваавтор статьи «The Many Ways of Getting Data Into Charts»

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