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

Сегодня мы займемся визуализацией данных с помощью 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»