D3.js - 入门






4.04/5 (10投票s)
D3JS 的基础知识 - 一个基于 JQuery 的数据可视化技术。
概述
数据可视化是任何软件应用的重要组成部分。它不仅有助于轻松快速地理解,有时还能以简单的方式呈现隐藏的信息,这些信息对于普通用户来说可能需要很长时间才能理解。在本文中,我们将尝试了解一种如此流行的数据可视化技术——D3.js,它最近在数据可视化工程师中获得了很高的声誉。
本文面向 D3.js 的初学者,但是,由于 D3.js 是一项基于 Web 的技术,读者应该对 HTML、CSS、AJAX 等常见的 Web 技术有所了解,才能充分利用本文。此外,由于 D3.js 本身是一项基于 JQuery 的技术,因此了解 JQuery 也很重要,尽管对 SVG 的基本了解就足够了。
本文涵盖了 D3.js 的基本概念。目的是让初学者开始接触这项技术,因此我暂时不想用太多额外信息来让初学者感到困惑。我计划将来发布更多文章,涵盖高级概念。
作为服务器端技术,我使用了 ASP.Net MVC 4.0。然而,如果您想使用任何其他服务器端技术,这不会有什么区别,因为 D3.js 是一项客户端技术,而服务器端技术仅用于将数据发送到客户端,然后由 D3.Js 进行处理。
引言
D3.js(或简称 D3,Data-Driven Documents 的缩写)是一个用于在 Web 浏览器中生成动态、交互式数据可视化的 JavaScript 库。
它基本上是一个 API 库,使用 SVG、JSON、JQuery、HTML5 和 CSS 来实现有效的数据可视化。
从技术上讲,D3.js 既不是图表库,也不是可视化库或图形库。它是现代 Web 技术之上的一个非常薄的层,用于帮助可视化工程师构建强大的数据可视化。D3.js JavaScript 库嵌入在 HTML 网页中,使用预构建的 JavaScript 函数来选择元素、创建 SVG 对象、为它们设置样式,或为它们添加过渡或动态效果,如果需要,还可以轻松地用 CSS 进行装饰。
可以使用简单的 D3.js 函数将大型数据集轻松绑定到 SVG 对象,从而生成丰富的文本/图形图表和图形。数据可以是各种格式,最常见的是 JSON 和 CSV。
为什么使用 D3.js
当今市场上有很多库可供选择,无论是免费还是付费的,那么为什么还要选择 D3.js 呢?以下是几个原因:
- 与许多其他库相比,D3.js 允许对最终的视觉结果进行极大的控制。
- 免费的开源技术,所有源代码都可以在 github 上找到。
- 简单易用,自由度高。
- 交互式
- 功能强大,几乎可以用 D3.js 绘制任何图表。
- 已经有很多现成的工具和可用的 示例。
基本术语
图表
Chart(图表)是绘制图形的占位符。通常它是一个简单的空 HTML Div 标签,其中将包含我们的 D3Js 图表。
Scale
Scale(比例尺)是将图表中的像素映射到图表中某个单位的函数。您的图表需要有一个坐标系统,通过比例尺,您可以定义图表的坐标系统。
这里,x 轴从 2013 年到 2015 年,y 轴从 $0 到 $5000。然而,SVG 是在一个大约 200 x 300 像素的框中绘制的。日期和像素本身不会相互映射,所以我们必须以某种方式指定映射。
请注意,y 轴是颠倒的!SVG 的原点 (0, 0) 在左上角,但在该图中,原点在左下角。
为了定义任何比例尺,您都需要一个定义域(domain)。定义域是您的数据值所在的任何值集。例如,5 年的收入可能是 [$2500.00,$3100.00,$1005.00,$5000.00,$3400.00],对于这些数据,定义域可能是 [$0.00, $5000,00]。
有三种类型的比例尺——定量比例尺、序数比例尺、时间比例尺。
定量比例尺 - 定量比例尺具有连续的定义域,例如实数集、日期等。有许多定量比例尺的子类型,如对数比例尺、幂比例尺等,但最常用*的定量比例尺是*线性比例尺*。在此比例尺中,映射是线性的,即输出范围值 y 可以表示为输入定义域值 x 的线性函数。例如,如果值 v1 = 2500 在 y 轴上占用 200 像素,则 v2 = 5000 通常应在 y 轴上占用 400 像素。
序数比例尺 - 序数比例尺用于离散的输入定义域,例如姓名、国家、组等。
时间比例尺 - 时间比例尺用于时间值。
下图显示了定量比例尺和序数比例尺的用法。左侧图表显示了按区域划分的销售额,其中 x 轴代表区域,y 轴显示销售额的定义域值。右侧图表显示了按年份划分的销售额,其中 x 轴代表年份数据,y 轴显示销售额的定义域值。
坐标轴
定义好比例尺后,您需要参考线来表示您的数据。这些参考线就是您的坐标轴。D3.js 库提供了许多方法和属性,通过这些方法和属性,您可以以多种方式绘制和装饰您的坐标轴。
定义坐标轴时您可能需要用到的一些常用函数:
d3.svg.axis() - 定义具有默认属性的坐标轴。
axis.scale([scale]) - 如果定义了[scale],则设置比例尺并返回坐标轴。如果未指定比例尺,则返回默认的线性比例尺。
axis.orient([orientation]) - 如果指定了[orientation],则设置方向并返回坐标轴。如果未指定方向,则返回默认的“bottom”。
方向决定了坐标轴的方向以及坐标轴刻度标签的位置。可以有 4 个有效值:
"top" - 水平坐标轴,刻度位于定义域路径的上方。
"bottom" - 水平坐标轴,刻度位于定义域路径的下方。
"left" - 垂直坐标轴,刻度位于定义域路径的左侧。
"right" - 垂直坐标轴,刻度位于定义域路径的右侧。
axis.ticks([arguments…]) - 此方法决定坐标轴上显示的刻度的数量和值。默认值为 10。
参数取决于比例尺的类型。例如,显示销售数据时,可以直接传递刻度数,这将根据传递的刻度数均匀地将定义域值分布在比例尺上;而在比例尺中显示时间值时,您可能需要同时传递时间间隔和刻度数,例如 axis.ticks(d3.time.year, 1)。
axis.tickValues([values]) - 此方法接受一个数组作为参数。如果指定了数组[values],则刻度标签将从此数组中获取,而不是默认数组。
一个简单的例子
让我们以一个简单的图表为例,来理解 D3 API 的用法。假设您在表格中有以下数据,您需要在您的网站上显示一个图表:
|
参考文献
对于 D3.js,您需要引用 JQuery(从 此处 下载)和 D3Js(从 此处 下载)。或者,您也可以直接从 CDN 引用。
Data
要绘制图表,您需要一些数据。在我的示例中,为了保持简单,我在函数中定义了提供的数据,但在典型的实际应用中,数据将来自服务器。
JavaScript -
var yearData;
var salesData;
var data =
[
{ 'Year': '2012', 'Sale': 2000 },
{ 'Year': '2014', 'Sale': 3000 },
{ 'Year': '2015', 'Sale': 5000 }
]
yearData = GetYears(data)
salesData = GetSales(data)
GetYear(data) 和 GetSales(data) 函数可以定义为:
JavaScript -
function GetYears(data) {
var result = [];
for (var i in data)
result.push(data[i].Year);
return result;
}
function GetSales(data) {
var result = [];
var max = 0.0;
result.push(max);
for (var i in data) {
if (max < data[i].Sale) {
max = data[i].Sale
}
}
result.push(max+50);
return result;
}
这里,'data' 是一个 JSON 对象,我们可以通过简单的 AJAX 调用从服务器获取。我从该对象创建了两个简单的数组 'yearData' 和 'salesData',这将帮助我们定义坐标轴。
图表
如前所述,chart 是我们图形的画布。我们需要一个简单的空 div 标签,我们可以将其转换为我们的 chart 对象。
HTML -
<div id="chart"></div>
JavaScript -
var margin = { top: 20, right: 30, bottom: 30, left: 40 },
width = 1000 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var chart = d3.select("#chart")
.append("svg") //append svg element inside #chart
.attr("width", width + (2 * margin.left) + margin.right) //set width
.attr("height", height + margin.top + margin.bottom); //set height
比例尺和坐标轴
现在您需要将图表与数据单位进行映射。为此,我们定义比例尺。任何比例尺都有一个定义域和一个值域。定义域代表您的数据值,值域代表您的图表区域(像素)。这里,我使用了序数比例尺来表示年份数据。
JavaScript -
var x = d3.scale.ordinal().domain(yearData).rangePoints([margin.left, width]);
var y = d3.scale.linear().domain(salesData).range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom").ticks(data.Year); //orient bottom because x-axis will appear below the bars
var yAxis = d3.svg.axis()
.scale(y)
.orient("left").ticks(10);
转换数据
现在我们已经定义了图表、坐标轴和比例尺,我们可以将数据转换为视觉显示。
JavaScript -
var valueline = d3.svg.line()
.x(function (d) { return x(d.Year); })
.y(function (d) { return y(d.Sale); });
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + margin.left + ",0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Sales Data");
// Add the valueline path.
chart.append("path")
.attr("class", "line")
.attr("d", valueline(data));
CSS
让我们用一些 CSS 来装饰我们的图表
<style type="text/css">
#chart text{
fill: black;
font: 10px sans-serif;
text-anchor: end;
}
.axis text{
font: 10px sans-serif;
}
.axis path, .axis line{
fill: none;
stroke : #fff;
shape-rendering: crispEdges;
}
body{
background: #1a1a1a;
color : #eaeaea;
padding : 10px;
}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
</style>
好了,您可以运行代码并查看结果了:
关注点
D3.js 是一项强大的数据可视化技术,它正迅速吸引着众多数据可视化工程师的兴趣。您几乎可以用它来绘制任何类型的图表。
本文并非深入探讨,而是涵盖了 D3.js 的基本概念。目的是让初学者开始接触这项技术。请继续关注我计划发布的更多高级主题,其中将涵盖一些更高级的概念。