NVD3.js 是一个免费且开源的 JavaScript 可视化库。它源自著名的 d3.js 可视化库。如果使用得当,此库对于日常任务甚至业务运营都非常强大。
例如,一个在线仪表盘。我们可以使用 NVD3.js 将数据编译到一个集中的空间中,并在简洁的图表和图形中可视化信息。这就是我们将在本文中探讨的内容。
第一次使用 NVD3.js 创建仪表盘可能令人望而生畏,但通过本教程,您应该具备必要的知识,可以动手开始构建一些很棒的东西。就我个人而言,我对网络上的可视化充满热情。它们既美观又富有意义。
实际用例:数据仪表盘
仪表盘几乎可以用于任何用途。只要您有要分析的数据,就可以开始了,无论是销售数据还是过去 20 年的平均天气。让我们构建类似这样的东西
查看 CodePen 上 Danny Englishby (@DanEnglishby) 编写的 仪表盘 NVD3.JS。
设置环境
要设置 NVD3 图表,我们需要三样东西
- NVD3 JavaScript 库
- NVD3 CSS 库
- D3.js 库(NVD3 的依赖项)
所有这些都可以通过 Cloudflare 的 CDN 网络 获得。这是一个包含所有这些资源的 HTML 模板,随时可以使用
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Making a Dashboard</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.css">
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.2/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.js"></script>
</body>
</html>
数据源
在本教程中,我认为使用一些已经格式化为 JSON 的原始事实数据是最简单的。我使用了两个信息来源:一个关于 全球平均气温随时间变化 的信息,另一个报告 世界人口统计数据。我已经将数据格式化为 JSON,因此可以随时复制粘贴!
创建折线图
让我们继续使用一些全球气温数据创建一个折线图。我用 JSON 编写的原始数据表示过去 20 年与全球平均气温相比的气温变化。
首先,我们将添加一个占位符元素,以便在执行 JavaScript 时将图表附加到该元素。
<div id="averageDegreesLineChart" class='with-3d-shadow with-transitions averageDegreesLineChart'>
<svg></svg>
</div>
然后在 </body>
标记之前的一些脚本标记中添加以下 JSON
var temperatureIndexJSON = [
{
key: "Temp +- Avg.",
values: [{ "x": 1998, "y": 0.45 }, { "x": 1999, "y": 0.48 }, { "x": 2000, "y": 0.5 }, { "x": 2001, "y": 0.52 }, { "x": 2002, "y": 0.55 }, { "x": 2003, "y": 0.58 }, { "x": 2004, "y": 0.6 }, { "x": 2005, "y": 0.61 }, { "x": 2006, "y": 0.61 }, { "x": 2007, "y": 0.61 }, { "x": 2008, "y": 0.62 }, { "x": 2009, "y": 0.62 }, { "x": 2010, "y": 0.62 }, { "x": 2011, "y": 0.63 }, { "x": 2012, "y": 0.67 }, { "x": 2013, "y": 0.71 }, { "x": 2014, "y": 0.77 }, { "x": 2015, "y": 0.83 }, { "x": 2016, "y": 0.89 }, { "x": 2017, "y": 0.95 }]
}
];
x
值是年份,y
值是以摄氏度为单位的温度。
拼图的最后一块是最重要的函数,它创建图表。名为 nv.addGraph()
的函数是 NVD3 中使用的主要函数,在其中,您初始化图表对象。在此示例中,我们使用的是 lineChart
对象,它可以根据视觉需求链接方法。
查看 JavaScript 注释以了解每行代码的作用。
nv.addGraph(function () {
var chart = nv.models.lineChart() // Initialise the lineChart object.
.useInteractiveGuideline(true); // Turn on interactive guideline (tooltips)
chart.xAxis
.axisLabel('TimeStamp (Year)'); // Set the label of the xAxis (Vertical)
chart.yAxis
.axisLabel('Degrees (c)') // Set the label of the xAxis (Horizontal)
.tickFormat(d3.format('.02f')); // Rounded Numbers Format.
d3.select('#averageDegreesLineChart svg') // Select the ID of the html element we defined earlier.
.datum(temperatureIndexJSON) // Pass in the JSON
.transition().duration(500) // Set transition speed
.call(chart); // Call & Render the chart
nv.utils.windowResize(chart.update); // Intitiate listener for window resize so the chart responds and changes width.
return;
});
查看 CodePen 上 Danny Englishby (@DanEnglishby) 编写的 折线图 NVD3.JS。
以一个的价格创建两个条形图
您会喜欢接下来的这两个图表的极简操作。NVD3.js 的强大功能能够在图表类型之间切换。您可以激活切换功能,以便用户可以在标准条形图和堆叠条形图之间切换。或者,您可以强制图表类型并使其不可更改。
以下示例准确地展示了如何操作。
堆叠多条形图
您知道那些在同一栏中将两个值堆叠在一起的条形图吗?这就是我们在这里要做的。
<div id="worldPopulationMultiBar" class="with-3d-shadow with-transitions worldPopulationMultiBar">
<svg></svg>
</div>
var populationBySexAndCountryJSON =[{"key":"Male","color":"#d62728","values":[{"label":"China","value":717723466.166},{"label":"India","value":647356171.132},{"label":"United States of America","value":157464952.272},{"label":"Indonesia","value":125682412.393},{"label":"Brazil","value":98578067.1},{"label":"Pakistan","value":93621293.316},{"label":"Nigeria","value":88370210.605},{"label":"Bangladesh","value":79237050.772},{"label":"Russian Federation","value":65846330.629},{"label":"Japan","value":61918921.999}]},{"key":"Female","color":"#1f77b4","values":[{"label":"China","value":667843070.834},{"label":"India","value":604783424.868},{"label":"United States of America","value":162585763.728},{"label":"Indonesia","value":124183218.607},{"label":"Brazil","value":101783857.9},{"label":"Pakistan","value":88521300.684},{"label":"Nigeria","value":85245134.395},{"label":"Bangladesh","value":77357911.228},{"label":"Russian Federation","value":76987358.371},{"label":"Japan","value":65224655.001}]}];
nv.addGraph(function ()
{
var chart = nv.models.multiBarChart()
.x(function (d) {
return d.label; // Configure x axis to use the "label" within the json.
})
.y(function (d) {
return d.value; // Configure y axis to use the "value" within the json.
}).margin({top: 30, right: 20, bottom: 50, left: 85}) // Add some CSS Margin to the chart.
.showControls(false) // Turn of switchable control
.stacked(true); // Force stacked mode.
chart.xAxis.axisLabel('Countries'); // add label to the horizontal axis
chart.yAxis.tickFormat(d3.format('0f')); // Round the yAxis values
d3.select('#worldPopulationMultiBar svg') // Select the html element by ID
.datum(populationBySexAndCountryJSON) // Pass in the data
.transition().duration(500) // Set transition speed
.call(chart); // Call & Render chart
nv.utils.windowResize(chart.update); // Intitiate listener for window resize so the chart responds and changes width.
return;
});
此处 JavaScript 中的两个重要设置是 .showControls
和 .stacked
布尔值。它们都按字面意思执行:将图形强制为堆叠条形图,并且不允许切换图表类型。您很快就会了解我的意思。
查看 CodePen 上 Danny Englishby (@DanEnglishby) 编写的 多堆叠条形图 NVD3.JS。
标准多条形图
现在,让我们做一些更传统的事情,将值并排比较,而不是将它们堆叠在同一栏中。
这使用了与堆叠示例几乎相同的代码,但我们可以将 .stacked
布尔值更改为 false
。这当然会将堆叠条形图变成普通条形图。
<div id="worldPopulationMultiBar" class="with-3d-shadow with-transitions worldPopulationMultiBar">
<svg></svg>
</div>
var populationBySexAndCountryJSON = [{"key":"Male","color":"#d62728","values":[{"label":"China","value":717723466.166},{"label":"India","value":647356171.132},{"label":"United States of America","value":157464952.272},{"label":"Indonesia","value":125682412.393},{"label":"Brazil","value":98578067.1},{"label":"Pakistan","value":93621293.316},{"label":"Nigeria","value":88370210.605},{"label":"Bangladesh","value":79237050.772},{"label":"Russian Federation","value":65846330.629},{"label":"Japan","value":61918921.999}]},{"key":"Female","color":"#1f77b4","values":[{"label":"China","value":667843070.834},{"label":"India","value":604783424.868},{"label":"United States of America","value":162585763.728},{"label":"Indonesia","value":124183218.607},{"label":"Brazil","value":101783857.9},{"label":"Pakistan","value":88521300.684},{"label":"Nigeria","value":85245134.395},{"label":"Bangladesh","value":77357911.228},{"label":"Russian Federation","value":76987358.371},{"label":"Japan","value":65224655.001}]}];
nv.addGraph(function () {
var chart = nv.models.multiBarChart()
.x(function (d) {
return d.label; // Configure x axis to use the "label" within the json.
})
.y(function (d) {
return d.value; // Configure y axis to use the "value" within the json.
}).margin({top: 30, right: 20, bottom: 50, left: 85}) // Add some CSS Margin to the chart.
.showControls(false) // Turn of switchable control
.stacked(false); // ***Force normal bar mode.***
chart.xAxis.axisLabel('Countries'); // add label to the horizontal axis
chart.yAxis.tickFormat(d3.format('0f')); // Round the yAxis values
d3.select('#worldPopulationMultiBar svg') // Select the html element by ID
.datum(populationBySexAndCountryJSON) // Pass in the data
.transition().duration(500) // Set transition speed
.call(chart); // Call & Render chart
nv.utils.windowResize(chart.update); // Intitiate listener for window resize so the chart responds and changes width.
return;
});
设置的唯一更改为我们提供了全新的图表外观。
查看 CodePen 上 Danny Englishby (@DanEnglishby) 编写的 多条形图 NVD3.JS。
使用一组代码进行最小的更改,您只需花费一个的价格就创建了两个很棒的图表。为您点赞!
当然,如果您希望能够切换图表,则还有一个最后的设置。将 .showControls
更改为 true
并删除 .stacked
选项。您会在图表顶部看到一些控件。单击它们将在堆叠图表和标准图表之间切换视图。
查看 CodePen 上 Danny Englishby (@DanEnglishby) 编写的 可切换多条形图 NVD3.JS。
创建仪表盘
在 Web 开发的世界里,我最喜欢看的莫过于仪表盘了。它们永不过时,而且外观极佳。通过使用我们已经介绍过的图表技术,我们可以在单个网页上创建自己的响应式仪表盘。
如果您还记得之前 JavaScript 代码段中的内容,则每个图表都设置了一个带有侦听器的函数:nv.utils.windowResize(chart.update);
这个神奇的函数会为您调整图表大小,就像在 CSS 中将其设置为 width: 100%
一样。但它不仅会缩小,还会根据屏幕大小移动和重构图形。非常棒!我们只需要关心高度即可。我们可以通过将 flexbox 应用于分配给图表元素的类来设置它。
让我们将到目前为止的所有内容捆绑到一个仪表盘中,方法是将每个图表元素包装在一个 flexbox 容器中。应用少量 CSS 以进行 flex 和高度设置,最后,将所有脚本编译成一个(或者,您可以在自己的项目中将它们分开)。
查看 CodePen 上 Danny Englishby (@DanEnglishby) 编写的 仪表盘 NVD3.JS。
总结
本教程希望能让你掌握构建数据可视化的基础知识,并最终将它们添加到生产仪表板中。即使你只想玩玩这些概念,我相信你的脑海中也会涌现出许多关于如何将不同类型的数据转化为令人惊叹的视觉效果的想法。
看起来 nvd3.js 只是 d3 的一个包装器,使用它而不是直接使用 d3 本身有什么优势呢?
本质上它是一个包装器,但优势在于它提供了一套预先配置的图表,这些图表看起来很美观。你无需陷入 d3.js 庞大的 API 中来创建图表。它也能够快速开发。不过我理解你的观点。