65.9K
CodeProject 正在变化。 阅读更多。
Home

D3.js - 入门

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.04/5 (10投票s)

2015年9月28日

CPOL

8分钟阅读

viewsIcon

33197

downloadIcon

869

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 Framework

为什么使用 D3.js

当今市场上有很多库可供选择,无论是免费还是付费的,那么为什么还要选择 D3.js 呢?以下是几个原因:

  1. 与许多其他库相比,D3.js 允许对最终的视觉结果进行极大的控制。
  2. 免费的开源技术,所有源代码都可以在 github 上找到。
  3. 简单易用,自由度高。
  4. 交互式
  5. 功能强大,几乎可以用 D3.js 绘制任何图表。
  6. 已经有很多现成的工具和可用的 示例

 

基本术语

图表

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 的用法。假设您在表格中有以下数据,您需要在您的网站上显示一个图表:

   
年份 销售
2013 $2000
2014 $3000
2015 $5000

参考文献

对于 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>

 

好了,您可以运行代码并查看结果了:

Result

关注点

D3.js 是一项强大的数据可视化技术,它正迅速吸引着众多数据可视化工程师的兴趣。您几乎可以用它来绘制任何类型的图表。

本文并非深入探讨,而是涵盖了 D3.js 的基本概念。目的是让初学者开始接触这项技术。请继续关注我计划发布的更多高级主题,其中将涵盖一些更高级的概念。

© . All rights reserved.