实验目的:

熟悉 D3 数据可视化的使用方法。

实验原理:

D3 的全称是(Data-Driven Documents),是一个被数据驱动的文档,其实就是 一个 JavaScript 的函数库,使用它主要是用来做数据可视化的。本次实践主要介绍D3一些最基本的使用方法,以及生成一些比较简单的图表。

  D3 是一个 JavaScript 函数库。它只有一个文件,在 HTML 中引用即可。有两种方法:(1)下载 D3.js 的文件,解压后,在 HTML 文件中包含相关的 js 文件即可。(2)还可以直接包含网络的链接,这种方法较简单:<script src="http://d3js.org/d3.v3.min.js"charset="utf-8"></script>    但使用的时候要保持网络连接有效,不能再断网的情况下使用。D3 可以接受几乎任何数字数组,字符串,或对象(本身包含其他数组或键/值 对),可以处理 JSON 和 GeoJSON。

实验环境:

  IE9 以上或 Firefox 或 Chrome(推荐)等浏览器、Notepad++等编辑工具。D3.js库。

实验步骤:

题目一:制作一个简单的柱形图。
1、打开Notepad++,新建文件,并编辑好html框架。

<html>
<head>
<meta charset="utf-8">
<title>完整的柱形图</title>
<style>
/* 设置柱形图的颜色 */
.MyRect {
fill: green; /* 修改颜色为绿色 */
}
/* 设置文字的样式 */
.MyText {
font-size: 12px;
text-anchor: middle;
fill: blue; /* 文字颜色为蓝色 */
}
/* 设置坐标轴的样式 */
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
</style>
</head>
2、添加 SVG 画布。
  要绘图,首要需要的是一块绘图的“画布”。HTML5 提供两种强有力的“画布”:SVG 和 Canvas。
  SVG,指可缩放矢量图形(Scalable Vector Graphics),是用于描述二维矢量图 形的一种图形格式,是由万维网联盟制定的开放标准。SVG 使用 XML 格式来定义 图形,除了 IE8 之前的版本外,绝大部分浏览器都支持 SVG,可将 SVG 文本直接嵌 入 HTML 中显示。Canvas 是通过 JavaScript 来绘制 2D 图形,是 HTML 5 中新增的元素。
  D3 虽然没有明文规定一定要在 SVG 中绘图,但是 D3 提供了众多的 SVG 图形 的生成器,它们都是只支持 SVG 的。因此,建议使用 SVG 画布。在 body 标签中加 入代码。

<body>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
// 画布大小
var width = 400;
var height = 400; // 在 body 里添加一个 SVG 画布
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height); // 画布周边的空白
var padding = {left: 30, right: 30, top: 20, bottom: 20};

3、定义数据和比例尺

在添加画布的代码后面加入以下代码。

        // 定义一个数组
var dataset = [16, 23, 54, 46, 33, 24, 19, 37, 9]; // x 轴的比例尺
var xScale = d3.scale.ordinal()
.domain(d3.range(dataset.length))
.rangeRoundBands([0, width - padding.left - padding.right], 0.1); // y 轴的比例尺
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset)])
.range([height - padding.top - padding.bottom, 0]);

4、定义坐标轴

        // 定义 x 轴
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom"); // 定义 y 轴
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");

5、添加矩形和文字元素

        // 添加矩形元素
var rects = svg.selectAll(".MyRect")
.data(dataset)
.enter()
.append("rect")
.attr("class", "MyRect")
.attr("transform", "translate(" + padding.left + "," + padding.top + ")")
.attr("x", function(d, i) {
return xScale(i) + rectPadding / 2;
})
.attr("y", function(d) {
return yScale(d);
})
.attr("width", xScale.rangeBand() - rectPadding)
.attr("height", function(d) {
return height - padding.top - padding.bottom - yScale(d);
});
// 添加文字元素
var texts = svg.selectAll(".MyText")
.data(dataset)
.enter()
.append("text")
.attr("class", "MyText")
.attr("transform", "translate(" + padding.left + "," + padding.top + ")")
.attr("x", function(d, i) {
return xScale(i) + rectPadding / 2;
})
.attr("y", function(d) {
return yScale(d);
})
.attr("dx", function() {
return (xScale.rangeBand() - rectPadding) / 2;
})
.attr("dy", function(d) {
return 20;
})
.text(function(d) {
return d;
});

6.添加坐标轴的元素

        // 添加 x 轴
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + padding.left + "," + (height - padding.bottom) + ")")
.call(xAxis); // 添加 y 轴
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + padding.left + "," + padding.top + ")")
.call(yAxis);
</script>
</body>
</html>

最后运行结果如下图所示:

题目二:制作动态的柱形图

  D3 提供了 4 个方法用于实现图形的过渡:
1) transition()启动过渡效果。其前后是图形变化前后的状态(形状、位置、颜 色等等)。D3 会自动对两种颜色(红色和铁蓝色)之间的颜色值(RGB值)进行插值计算,得到过渡用的颜色值。
2) duration()指定过渡的持续时间,单位为毫秒。如 duration(3000),指持续 3秒。
3) ease()指定过渡的方式,常用的有:linear:普通的线性变化;circle:慢慢地 到达变换的最终状态;elastic:带有弹跳的到达最终状态;bounce:在最终 状态处弹跳几次。
4) delay()指定延迟的时间,表示一定时间后才开始转变,单位同样为毫秒。此 函数可以对整体指定延迟,也可以对个别指定延迟。
  下面我们将在题目一完成的柱形图的基础上稍作修改,做成一个带动态效果的 柱形图。把题目一中添加矩形元素和添加文字元素的代码换成如下代码,就可以启 动过渡效果,让各柱形和文字缓慢升至目标高度,并且在目标处跳动几次。

        // 添加矩形元素
var rects = svg.selectAll(".MyRect")
.data(dataset)
.enter()
.append("rect")
.attr("class", "MyRect")
.attr("transform", "translate(" + padding.left + "," + padding.top + ")")
.attr("x", function(d, i) {
return xScale(i) + rectPadding / 2;
})
.attr("width",xScale.rangeBand() - rectPadding)
.attr("y", function(d) {
var min = yScale.domain()[0];
return yScale(min);
})
.attr("height", function(d) {
return 0;
});
.transition()
.delay(function(d,i){
return i * 200;
})
.duration(2000)
.ease("bounce")
.attr("y",function(d){
return yScale(d);
})
.attr("height",function(d){
return height - padding.top - padding.bottom - yScale(d);
}); // 添加文字元素
var texts = svg.selectAll(".MyText")
.data(dataset)
.enter()
.append("text")
.attr("class", "MyText")
.attr("transform", "translate(" + padding.left + "," + padding.top + ")")
.attr("x", function(d, i) {
return xScale(i) + rectPadding / 2;
})
.attr("dx", function() {
return (xScale.rangeBand() - rectPadding) / 2;
})
.attr("dy", function(d) {
return 20;
})
.text(function(d) {
return d;
});
.attr("y", function(d) {
var min = yScale.domain()[0];
return yScale(min);
})
.transition()
.delay(function(d,i){
return i * 200;
})
.duration(2000)
.ease("bounce")
.attr("y",function(d){
return yScale(d);
})
可运行程序,结果如下所示:

题目三:制作饼形图。
  布局是 D3 中一个十分重要的概念。布局的作用是:将不适合用于绘图的数据转 换成了适合用于绘图的数据。
  D3 总共 提供 了 12 个布 局:饼状图(Pie)、力导向图(Force)、弦图(Chord)、树状图(Tree)、集群图(Cluster)、捆图(Bundle)、打包图(Pack)、直方图(Histogram)、分区图(Partition)、堆栈图(Stack)、矩阵树图 (Treemap)、层级图(Hierarchy)。12 个布局中,层级图(Hierarchy)不能直接使用。集群图、打包图、分区图、树状图、矩阵树图是由层级图扩展来的。这些布局的作用都是将某种数据转换成有利于可视化的另一种数据。在布局的应用中,最简单的就是饼状图。
1、定义一个饼状图布局
  定义布局的代码为:var pie = d3.layout.pie();此时 pie 可以当做函数使用。然后将数组 dataset(里面是要可视化的数据)作为 pie()的参数,返回值 piedata 就是转换后的数据。var piedata = pie(dataset)。

<html>
<head>
<meta charset="utf-8">
<title>饼状图</title>
</head>
</style>

</style>
<body>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
// 画布大小
var width = 400;
var height = 400;
// 数据集
var dataset = [11, 6, 34, 27, 13, 9];
// 创建 SVG 画布
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
// 定义一个布局
var pie = d3.layout.pie();
var piedata = pie(dataset);

  首先定义一个布局,返回值赋給变量 pie,此时 pie 可以当做函数使用,接着将数组 dataset 作为 pie()的参数,返回值给 piedata。

2、绘制图形
  SVG 有一个叫做路径的元素,它可以结合使用直线,曲线等来制作各种 不规则的复杂的图形。 通过布局转换后的数据 piedata 很难计算得到路径值。 为此,我们需要用到生成器。 这里要用到的叫做弧生成器,能够生成弧的路径,因为饼图的每一部分都是一 段弧。

        // 定义弧生成器
var outerRadius = 150; // 外半径
var innerRadius = 0; // 内半径,为 0 则中间没有空白 var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
弧生成器返回的结果赋值给 arc。 arc 可以当做一个函数使用,把 piedata 作为参数传入,即可得到路径值。 接下来,在<svg>里添加分组元素(g),每一个分组用于存放一段弧的相关元 素。 再对每个<g>元素,添加<path>。

        // 添加分组元素,每个分组对应一段弧
var arcs = svg.selectAll("g")
.data(piedata)
.enter()
.append("g")
.attr("transform", "translate(" + (width / 2) + "," + (height / 2) + ")");
// 添加路径元素,绘制弧
arcs.append("path")
.attr("fill", function(d, i) {
return color(i); // 根据索引设置颜色
})
.attr("d", function(d) {
return arc(d); // 使用弧生成器生成路径
})
定义颜色比例尺。 color 是一个颜色比例尺,它能根据传入的索引号获取相应的颜色值。

            .outerRadius(outerRadius);

        // 定义颜色比例尺
var color = d3.scale.category10(); var arcs = svg.selectAll("g")
  然后在每一个弧线中心添加文本。运行结果如下:
        // 添加文本元素,显示数据值
arcs.append("text")
.attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")"; // 将文本定位到弧的中心
})
.attr("text-anchor", "middle")
.text(function(d) {
return d.data; // 显示数据值
}); // 打印数据集和转换后的数据到控制台
console.log("原始数据集:", dataset);
console.log("转换后的数据:", piedata);
</script>
</body>
</html>

题目四:制作交互式的饼形图。
交互是指用户输入了某种指令后程序就可做出某种响应。 对可视化图表来说,交互能使图表更加生动,能表现更多内容。 例如,拖动图表中某些图形、鼠标滑到 图形上出现提示框、用触屏放大或缩小图形等等。 用户用于交互的工具一般有三 种:鼠标、键盘、触屏。 在 D3 中,每一个选择集都有 on()函数,用于添加事件监听器。 on()的第一个参 数是监听的事件,第二个参数是监听到事件后响应的内容,第二个参数是一个函 数。 鼠标常用的事件有:
  click - 鼠标单击某元素时,相当于 mousedown 和 mouseup 组合在一起。
mouseover - 光标放在某元素上。
mouseout - 光标从某元素上移出来时。
  mousemove - 鼠标被移动的时候。
mousedown - 鼠标按钮被按下。
mouseup - 鼠标按钮被松开。
下面开始进行简单的交互式饼形图制作,目标是在上面的饼形图的基础上加入mouseover 和 mouseout 事件,mouseover 某部分时变换成黄色,mouseout 时恢复原色。 在代码中加入如下代码。

        // 添加路径元素,绘制弧
arcs.append("path")
.attr("fill", function(d, i) {
return color(i); // 根据索引设置颜色
})
.attr("d", function(d) {
return arc(d); // 使用弧生成器生成路径
})
.on("mouseover", function(d, i) {
d3.select(this)
.attr("fill", "yellow"); // 鼠标悬停时变为黄色
})
.on("mouseout", function(d, i) {
d3.select(this)
.transition()
.duration(500)
.attr("fill", color(i)); // 鼠标移出时恢复原色
});

运行结果为:

实验心得:
     通过本次实验,熟练的掌握了D3数据可视化的使用方法,通过在使用Notepad++软件,来编写和运行代码。在使用Notepad++软件的途中,学习到了在运行代码之时,要将文件先保存为.html文件形式,这样才可以使用浏览器来得出相关数据图。通过实验,我熟练掌握了D3的基本使用方法。 从创建SVG画布,到定义数据和比例尺,再到添加各种图形元素和坐标轴,每一个步骤都让我对D3的工作原理有了更清晰的认识。 在制作柱形图时,我学会了利用比例尺将数据映射到合适的图形尺寸,通过调整坐标轴样式和图形颜色,使图表更加美观和易读。 这让我意识到,数据可视化不仅仅是将数据呈现出来,更重要的是如何以一种直观、有效的方式展示数据,帮助用户更好地理解数据背后的信息。 制作动态柱形图的过程让我对D3的过渡效果有了深刻的理解。 通过transition()、duration()、ease()和delay()等方法,能够实现图形的动态变化,使图表更加生动有趣,这种动态效果增加了图表的观赏性,突出了数据的变化趋势。饼形图的制作让我接触到了D3中的布局概念。布局的作用是将原始数据转换为适合绘图的数据格式,这使得复杂图形的绘制变得更加容易。在制作饼形图时,通过d3.layout.pie()定义布局,利用弧生成器绘制饼图的每一部分,并学会了添加文本标签和颜色比例尺,使饼图更加完整和直观。这让我认识到,合理运用布局和生成器可以大大简化复杂图形的绘制过程,提高开发效率。交互式饼形图的制作则让我体验到了D3的交互功能的强大。通过on()函数添加事件监听器,我能够实现鼠标悬停和移出时图形颜色的变化,增强了用户与图表的交互性。这种交互性可以让用户更加深入地探索数据,发现数据中的隐藏信息。在实际项目中,交互功能可以提升用户体验,使数据可视化更加实用和高效。然而,在实验过程中我也遇到了一些问题。例如,在调整图形样式和位置时,由于对D3的属性和方法理解不够深入,导致出现了一些布局错乱的情况。在处理复杂数据和图形时,性能问题也逐渐显现出来。通过查阅资料和不断调试,我逐渐解决了这些问题,这也让我明白在学习和实践过程中,遇到问题并不可怕,关键是要学会如何分析和解决问题。 总的来说,这次实验让我对D3数据可视化有了全面的认识和掌握。

实验二:D3数据可视化基础的更多相关文章

  1. Python数据可视化基础讲解

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:爱数据学习社 首先,要知道我们用哪些库来画图? matplotlib ...

  2. 数据可视化基础专题(十二):Matplotlib 基础(四)常用图表(二)气泡图、堆叠图、雷达图、饼图、

    1 气泡图 气泡图和上面的散点图非常类似,只是点的大小不一样,而且是通过参数 s 来进行控制的,多的不说,还是看个示例: 例子一: import matplotlib.pyplot as plt im ...

  3. 数据可视化基础专题(三):Pandas基础(二) csv导入与导出

    1.csv导入 1.1 csv导入 .read_csv()函数 pandas.read_csv(filepath_or_buffer: Union[str, pathlib.Path, IO[~Any ...

  4. 数据可视化基础专题(二):Pandas基础(一) excel导入与导出

    1.Excel 1.1 Excel导入 read_excel() pandas.read_excel(io, sheet_name=0, header=0, names=None, index_col ...

  5. 数据可视化基础专题(十):Matplotlib 基础(二) 自定义配置文件和绘图风格(rcParams和style)

    https://matplotlib.org/api/rcsetup_api.html#module-matplotlib.rcsetup 一.什么是rcParams?我们在使用matplotlibl ...

  6. 数据可视化基础专题(十五):pyecharts 基础(二)flask 框架整合

    Flask 前后端分离 Step 1: 新建一个 Flask 项目 $ mkdir pyecharts-flask-demo $ cd pyecharts-flask-demo $ mkdir tem ...

  7. D3 数据可视化实战 笔记

    学习真是件奇妙的事情.这本书我之前都看过,有些的知识点却完全没有印象. 总结:把用到的知识好好研究:平时可以了解其他技术的基础,把相关的资料和难点记录下来. javascript陷阱 1.变量类型 v ...

  8. 数据可视化基础专题(五):Pandas基础(四) 生成对象

    引言 先介绍下 Pandas 的数据结构,毕竟数据结构是万物的基础. Pandas 有两种主要的数据结构: Series 和 DataFrame 模块导入 首先我们在代码中引入 Pandas 和 Nu ...

  9. 数据可视化基础专题(十三):Matplotlib 基础(五)常用图表(三)环形图、热力图、直方图

    环形图 环形图其实是另一种饼图,使用的还是上面的 pie() 这个方法,这里只需要设置一下参数 wedgeprops 即可. 例子一: import matplotlib.pyplot as plt ...

  10. 【笔记】matplotilb数据可视化基础

    matplotilb基础 matplotilb是我们使用的一个基础的可视化方法 一般来说,使用matplotilb是较为专业的绘制图形的选择 不需要很专业的时候可以只是用matplotilb的子模块p ...

随机推荐

  1. [Flink] Flink运行过程中Flink作业运行崩溃,且`TaskManager`报:"Association with remote system [akka.tcp://flink@flink-236429.ns-69020:6123] has failed, address is now gated for [50] ms. Reason: [Disassociated]"

    1 问题描述 一个长期正常运行的FlinkSqlCdcJob(Flink 1.12 . Flink CDC 1.3.0),运行崩溃,且TaskManager的日志(taskmanager.log)报: ...

  2. 收藏几个常用的vue自定义组件,抄自 他人,以防丢失

    在 Vue,除了核心功能默认内置的指令 ( v-model 和 v-show ),Vue 也允许注册自定义指令.它的作用价值在于当开发人员在某些场景下需要对普通 DOM 元素进行操作. Vue自定义指 ...

  3. CDS标准视图:催款范围 I_DunningArea

    视图名称:催款范围 I_DunningArea 视图类型:基础 视图代码: 点击查看代码 @AccessControl.authorizationCheck: #CHECK //authority c ...

  4. consul简介

    Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置. Consul是分布式的.高可用的.可横向扩展的.它具备以下特性 : 服务发现:consul通过DNS或者HTT ...

  5. 在 Windows 10 上实现免密码 SSH 登录

    前言 在日常开发中,SSH(Secure Shell)作为一种安全的远程登录协议,广泛用于 Linux 和 Windows 系统之间的连接.为了提高效率,我们可以通过配置免密码登录,省去每次连接时输入 ...

  6. Superset 用户集成方案

    注意,一下内容来自外网浏览器翻译,本人使用了将superset集成进入第三方系统,superset采用自定义身份验证+第三系统iframe嵌入方式,但是这个方式存在一个问题,iframe与redire ...

  7. MySQL插入修改和删除

    原文链接:https://blog.liuzijian.com/post/36d9bcaa-2ba7-26ca-6f97-b8ef7a058e95.html 插入 支持一次性插入多行,支持子查询 IN ...

  8. HiJobQueue:一个简单的线程安全任务队列

    HiJobQueue:一个简单的线程安全任务队列 概述 HiJobQueue 是一个线程安全的任务队列,用于在多线程环境中管理和执行异步任务.它的设计参考了 Cobalt 项目中的 JobQueue, ...

  9. Nodify学习 二:添加节点

    Nodify学习 一:介绍与使用 - 可乐_加冰 - 博客园 (cnblogs.com) Nodify学习 二:添加节点 - 可乐_加冰 - 博客园 (cnblogs.com) 添加节点(nodes) ...

  10. mybatis之增删改查

    核心配置文件中配置数据库连接及注册mapper.xml mapper.xml用来编写执行的sql(namespace为对应的接口类,标签id为接口类中的方法名) User为实体对象类 UserDao为 ...