将数据导入图表的多重方法

Avatar of Dan Englishby
Dan Englishby

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

如今,数据无处不在,无论是纯文本文件、REST API、在线 Google 表格……应有尽有!正是这种多样的环境使得构建图表不仅仅局限于本地项目中的数据库——哪里有数据,哪里就有方法。

这正是我们将在本文中探讨的内容:使用各种来源的数据创建 JavaScript 数据可视化。

如果您想跟随本文并创建任何我们在此处介绍的可视化效果,我们将使用 Chart.js,因此请获取它并将其包含在您自己的环境中。

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

来源 1:HTML 数据表格

许多网站都有数据表格,为什么不呢?它们是显示数据的好方法,这也是它们被创建的目的。但是,如果您可以通过其中的数据生成可视化效果——并且无需付出更多努力——那岂不是更好吗?

使用少量 JavaScript,可以将 HTML 表格中的数据与 HTML 隔离,并为图表做好准备。请查看以下数据表格。

年份 销售商品数量 营业额(美元) 利润(美元)
2016 10 200 89
2017 25 550 225
2018 55 1200 600
2019 120 2450 1100

它包含了某家企业的销售数据。现在,如果我们可以将其绘制成图表,它将既具有视觉吸引力,又能帮助用户获得洞察力。所以让我们来做吧!

首先,让我们为图表定义一个函数。这直接来自 Chart.js 库,因此值得与 文档 进行交叉参考,如果某些内容不清楚的话。我添加了一些注释来突出关键部分。

function BuildChart(labels, values, chartTitle) {
  var ctx = document.getElementById("myChart").getContext('2d');
  var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
      labels: labels, // Our labels
      datasets: [{
        label: chartTitle, // Name the series
        data: values, // Our values
        backgroundColor: [ // Specify custom colors
          '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: [ // Add custom color borders
          '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 // Specify bar border width
      }]
    },
    options: {
      responsive: true, // Instruct chart js to respond nicely.
      maintainAspectRatio: false, // Add to prevent default behavior of full-width/height 
    }
  });
  return myChart;
}

现在我们有了用于创建图表数据的函数,让我们编写表格的 HTML 并添加一个 Chart.js 可以用来注入其图表功能的画布元素。这与上面表格示例中的数据完全相同。

<table class="table" id="dataTable">
  <thead>
    <th>Year</th>
    <th>Items Sold</th>
    <th>Turnover ($)</th>
    <th>Profit ($)</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>

然后,我们需要使用原生 JavaScript 将表格解析成 JSON。Chart.js 将使用它来填充图表和图形。

var table = document.getElementById('dataTable');
var json = []]; // First row needs to be headers 
var headers =[];
for (var i = 0; i < table.rows[0].cells.length; i++) {
  headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi, '');
}

// Go through cells 
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 控制台中检查输出。以下是记录到控制台中的内容。

完美!我们的表头变成了变量,并映射到表格单元格中的内容。

剩下的就是将年份标签和销售商品数量的值映射到数组(Chart.js 的数据对象需要数组),然后将数据传递给图表函数。

此脚本将 JSON 值映射到年份数组。我们可以在前一个函数之后直接添加它。

// Map JSON values back to label array
var labels = json.map(function (e) {
  return e.year;
});
console.log(labels); // ["2016", "2017", "2018", "2019"]

// Map JSON values back to values array
var values = json.map(function (e) {
  return e.itemssold;
});
console.log(values); // ["10", "25", "55", "120"]

调用我们第一个代码段中的 BuildChart 函数(包括图表的名称),我们就可以得到从 HTML 表格数据生成的精美可视化效果。

var chart = BuildChart(labels, values, "Items Sold Over Time");

就是这样!图表数据现在已被隔离并传递到 JavaScript 可视化中并呈现。

查看 CodePen 上的示例
从 HTML 表格加载的条形图
,作者:Danny Englishby (@DanEnglishby)
CodePen 上。

来源 2:实时 API

世界上有很多公开的 API 可用,其中许多都包含丰富且有用的数据。让我们使用其中一个来演示如何使用实时数据填充图表。我将使用 福布斯 400 富豪榜 API 绘制世界上最富有的 10 个人。我知道,很酷,对吧?!我总是发现财富排名很有趣,而且这个 API 提供了更多数据。但现在,我们将请求数据以使用纯 JavaScript 显示包含姓名和实时净资产的图表!

首先,我们想再次定义一个图表函数,这次添加了一些更多选项。

function BuildChart(labels, values, chartTitle) {
  var data = {
    labels: labels,
    datasets: [{
      label: chartTitle, // Name the series
      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, // Instruct chart JS to respond nicely.
      maintainAspectRatio: false, // Add to prevent default behavior of full-width/height 
      scales: {
        xAxes: [{
          scaleLabel: {
            display: true,
            labelString: '$ Billion'
          }
        }],
        yAxes: [{
          scaleLabel: {
            display: true,
            labelString: 'Name'
          }
        }]
      },
    }
  });
  return myChart;
}

接下来,我们需要相同的 HTML 画布元素来呈现图表。

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

现在获取一些实时数据。让我们看看福布斯 API 调用在控制台中返回了什么。

如您从返回的 JSON 中看到的,有很多丰富的信息可以注入到图表中。所以,让我们来创建我们的排名吧!

使用一些简单的 JavaScript,我们可以从 API 请求数据,挑选出我们想要的值并将其映射到数组变量,最后传递我们的数据并呈现图表。

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
  if (this.readyState == 4 && this.status == 200) {
    var json = JSON.parse(this.response);
    // Map JSON labels  back to values array
    var labels = json.map(function (e) {
      return e.name;
    });
    // Map JSON values back to values array
    var values = json.map(function (e) {
      return (e.realTimeWorth / 1000); // Divide to billions in units of ten
    });
    BuildChart(labels, values, "Real Time Net Worth"); // Pass in data and call the chart
  }
};
xhttp.open("GET", "https://forbes400.herokuapp.com/api/forbes400?limit=10", false);
xhttp.send();

查看 CodePen 上的示例
从 RichListAPI 加载的图表
,作者:Danny Englishby (@DanEnglishby)
CodePen 上。

来源 3:Google 表格

到目前为止,我们已经研究了标准 HTML 表格和 API 中的数据来填充图表。但是,如果我们已经有了一个包含大量数据的现有 Google 表格呢?好吧,我们也可以用它来创建图表!

首先,访问 Google 表格有一些规则。

  • Google 表格必须发布。
  • Google 表格必须是公开的(即未设置为私有查看)。

只要这两个条件成立,我们就可以以 JSON 格式访问 Google 表格,这意味着,当然,我们可以将其绘制成图表!

这是一个 Google 表格,其中包含一些我公开发布的虚构数据。它包含三个数据字段:MachineId、Date 和 ProductsProduced。

现在,如果我们获取该表单的 URL,我们将记下最后一个斜杠后面的所有内容。

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

这是表单标识符,也是我们发送到 Google 的 GET 请求所需的标识符。要对 JSON 发出 GET 请求,我们将该字符串插入到另一个 URL 中的 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

以下是我们在控制台中获得的响应。

重要的部分是 feed.entry 对象数组。它保存重要的表单数据,当我们深入研究它时,它看起来像这样。

注意红色下划线的部分。Google 表格 API 在每个列名前面都加上了 gsx$(例如 gsx$date)。这些正是我们用来从对象中提取数据的方式,使用这些唯一生成的名称。因此,了解这一点后,是时候将数据插入到一些隔离的数组中,并将它们传递给我们的图表函数了。

function BuildChart(labels, values, chartTitle) {
  var data = {
    labels: labels,
    datasets: [{
      label: chartTitle, // Name the series
      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, // Instruct chart js to respond nicely.
      maintainAspectRatio: false, // Add to prevent default behavior of full-width/height 
      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 请求,映射我们的标签和值数组,最后调用传递数据的图表。

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

  // Map JSON labels  back to values array
  var labels = json.feed.entry.map(function (e) {
    return e.gsx$date.$t;
  });
      
  // Map JSON values back to values array
  var values = json.feed.entry.map(function (e) {
    return e.gsx$productsproduced.$t;
  });

  BuildChart(labels, values, "Production Data");
  }
};
xhttp.open("GET", "https://spreadsheets.google.com/feeds/list/1ySHjH6IMN0aKImYcuVHozQ_TvS6Npt4mDxpKDtsFVFg/od6/public/full?alt=json", false);
xhttp.send();

就这样!

查看 CodePen 上的示例
从 Google 表格加载的图表
,作者:Danny Englishby (@DanEnglishby)
CodePen 上。

您将用数据创建什么?

您可能已经了解到,我们可以通过多种方式获取数据来填充美观的图表和图形。只要我们有一些格式化的数字和数据可视化库,我们就可以掌握很多能力。

希望您现在正在思考您可能在哪里拥有数据以及如何将其插入图表!我们甚至没有涵盖此处的所有可能性。以下是一些您现在可以使用的更多资源,因为您已经掌握了图表制作技巧。

更多图表库

更多数据存储位置