利用D3.js实现数据可视化的简单示例

目录

一、D3.js选择器

二、数据绑定相关方法

三、DOM操作方法

四、事件监听

五、实现折线图案例

[1.首先引入 D3.js 库。](#1.首先引入 D3.js 库。)

2.然后获取数据(这里定义了销售数据数组作为数据)。

[3.接着创建一个 svg 元素作为画布](#3.接着创建一个 svg 元素作为画布)

[4.定义 x 轴和 y 轴的比例尺,x 轴使用 scaleBand 比例尺来处理离散的月份数据,y 轴使用 scaleLinear 比例尺根据销售金额的范围来确定坐标范围](#4.定义 x 轴和 y 轴的比例尺,x 轴使用 scaleBand 比例尺来处理离散的月份数据,y 轴使用 scaleLinear 比例尺根据销售金额的范围来确定坐标范围)

[5.分别添加 x 轴和 y 轴到 svg 画布上。](#5.分别添加 x 轴和 y 轴到 svg 画布上。)

6.定义折线生成器

7.使用数据绘制折线和数据点

8.监听事件并添加处理函数


使用D3.js过程中,我们一般需要创建画布、绑定数据、选择元素、操作元素、监听元素事件等,因此,需要先了解D3.js的选择器、数据绑定方式、DOM操作方法、事件监听等。

一、D3.js选择器

  1. d3.select() :.
  • 选择第一个匹配的 DOM 元素。

  • 用法:`d3.select(selector)`,其中 `selector` 是 CSS 选择器字符串。

  1. d3.selectAll() :
  • 选择所有匹配的 DOM 元素。

  • 用法:`d3.selectAll(selector)`,其中 `selector` 是 CSS 选择器字符串。

二、数据绑定相关方法

1.enter() :

  • 为数据绑定过程中未匹配的元素创建新的 DOM 元素。

  • 用法:`selection.enter()`。

2.exit() :

  • 为数据绑定过程中多余的元素(即数据减少时)提供操作。

  • 用法:`selection.exit()`。

3.data() :

  • 将数据绑定到 DOM 元素上。

  • 用法:`selection.data(data)`,其中 `data` 是要绑定的数据。

三、DOM操作方法

1.attr() :

  • 获取或设置 DOM 元素的属性。

  • 用法:`selection.attr(name, value)`。

2.style() :

  • 获取或设置 DOM 元素的样式。

  • 用法:`selection.style(name, value)`。

3.text() :

  • 获取或设置 DOM 元素的文本内容。

  • 用法:`selection.text(value)`。

4.html() :

  • 获取或设置 DOM 元素的 HTML 内容。

  • 用法:`selection.html(value)`。

5.append() :

  • 在选定的元素中添加新的子元素。

  • 用法:`selection.append(name)`,其中 `name` 是新元素的标签名。

6.remove() :

  • 移除选定的元素。

  • 用法:`selection.remove()`。

四、事件监听

1.on() :

  • 为 DOM 元素添加事件监听器。

  • 用法:`selection.on(eventName, listener)`。

五、实现折线图案例

html 复制代码
DOCTYPE html><html lang="en">
<head>
  <meta charset="UTF-8"> 
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>D3.js实现折线图案例title>
  <style>
    svg {
      width: 600px;
      height: 400px;
      border: 1px solid #ccc;
    }
  style>
head>
<body>
  <script src="https://d3js.org/d3.v7.min.js">script>  <script>
    // 销售数据
    const salesData = [      { month: 'Jan', amount: 12000 },      { month: 'Feb', amount: 15000 },      { month: 'Mar', amount: 18000 },      { month: 'Apr', amount: 16000 },      { month: 'May', amount: 20000 },      { month: 'Jun', amount: 22000 }    ];
    // 定义 svg 画布
    const svg = d3.select('body').append('svg');
    // 定义 x 轴比例尺
    const xScale = d3.scaleBand()
     .domain(salesData.map(d => d.month))
     .range([0, 500])
     .padding(0.2);
    // 定义 y 轴比例尺
    const yScale = d3.scaleLinear()
     .domain([0, d3.max(salesData, d => d.amount)])
     .range([300, 0]);
    // 添加 x 轴
    svg.append('g')
     .attr('transform', 'translate(50,300)')
     .call(d3.axisBottom(xScale));
    // 添加 y 轴
    svg.append('g')
     .attr('transform', 'translate(50,0)')
     .call(d3.axisLeft(yScale));
    // 添加折线
    const line = d3.line()
     .x(d => xScale(d.month) + 25)
     .y(d => yScale(d.amount));

    svg.append('path')
     .datum(salesData)
     .attr('fill', 'none')
     .attr('stroke', 'steelblue')
     .attr('stroke-width', 2)
     .attr('d', line);
    // 添加数据点
    svg.selectAll('.dot')
     .data(salesData)
     .enter()
     .append('circle')
     .attr('class', 'dot')
     .attr('cx', d => xScale(d.month) + 25)
     .attr('cy', d => yScale(d.amount))
     .attr('r', 5)     .attr('fill', 'blue');
    // 添加提示框(简单示例,未完整实现交互)
    svg.selectAll('.dot')
     .on('mouseover', function (event, d) {
        d3.select(this).attr('r', 8);
        // 这里可以进一步完善提示框内容和样式的显示 
       console.log(`Month: ${d.month}, Amount: ${d.amount}`);
      })
     .on('mouseout', function (event, d) {
        d3.select(this).attr('r', 5);
      });
  script>
body>
html>

1.首先引入 D3.js 库。

<script src="https://d3js.org/d3.v7.min.js">script> <script>

2.然后获取数据(这里定义了销售数据数组作为数据)。

3.接着创建一个 svg 元素作为画布

const svg = d3.select('body').append('svg');

4.定义 x 轴和 y 轴的比例尺,x 轴使用 scaleBand 比例尺来处理离散的月份数据,y 轴使用 scaleLinear 比例尺根据销售金额的范围来确定坐标范围

// 定义 x 轴比例尺

const xScale = d3.scaleBand()

.domain(salesData.map(d => d.month))

.range([0, 500])

.padding(0.2);

  • d3.scaleBand():创建一个分带(离散)比例尺,适用于处理分类数据。
  • domain(salesData.map(d => d.month)) :设置比例尺的输入域(Domain)。这里从salesData数组中提取每个数据对象的month属性,形成一个包含所有月份的数组作为输入域。
  • range([0, 500]):设置比例尺的输出范围(Range),将输入域映射到从 0 到 500 的区间。
  • padding(0.2):设置每个类别之间的间隔为带宽的 20%,避免数据标签相互重叠。

// 定义 y 轴比例尺

const yScale = d3.scaleLinear()

.domain([0, d3.max(salesData, d => d.amount)])

.range([300, 0]);

const yScale = d3.scaleLinear()

.domain([0, d3.max(salesData, d => d.amount)])

.range([300, 0]);

  • d3.scaleLinear():创建一个线性比例尺,用于处理连续数据。
  • domain([0, d3.max(salesData, d => d.amount)]) :设置输入域。这里输入域的下限是 0,上限是salesData数组中amount属性的最大值,通过d3.max函数计算得出。
  • range([300, 0]):设置输出范围。在 SVG 坐标系中,y 轴是从上到下递增的,所以这里将较大的数据值映射到较小的 y 坐标,范围是从 300(底部)到 0(顶部)。

5.分别添加 x 轴和 y 轴到 svg 画布上。

// 添加 x 轴

svg.append('g')

.attr('transform', 'translate(50,300)')

.call(d3.axisBottom(xScale));

// 添加 y 轴

svg.append('g')

.attr('transform', 'translate(50,0)')

.call(d3.axisLeft(yScale));

  • svg.append('g') :在 SVG 元素中添加一个<g>(分组)元素,用于容纳坐标轴的所有组件。
  • attr('transform', 'translate(50,300)') :对<g>元素应用平移变换,将其移动到坐标 (50, 300) 的位置。这是为了将 x 轴放置在合适的位置上。
  • call(d3.axisBottom(xScale)) :调用d3.axisBottom函数创建一个底部坐标轴,并将xScale比例尺应用到该坐标轴上,然后将坐标轴添加到<g>元素中。
  • call(d3.axisLeft(yScale)) 调用d3.axisLeft函数创建一个左侧坐标轴,并将yScale比例尺应用到该坐标轴上,然后将坐标轴添加到<g>元素中。

6.定义折线生成器

// 添加折线

const line = d3.line()

.x(d => xScale(d.month) + 25)

.y(d => yScale(d.amount));

svg.append('path')

.datum(salesData)

.attr('fill', 'none')

.attr('stroke', 'steelblue')

.attr('stroke-width', 2)

.attr('d', line);

  • d3.line():创建一个折线生成器。
  • x(d => xScale(d.month) + 25) :定义折线在 x 方向上的坐标获取方式。对于每个数据点,通过xScale比例尺将月份数据映射到 x 坐标,并加上 25 是为了使折线稍微偏离坐标轴一点,让数据点在坐标轴刻度的中间位置。
  • y(d => yScale(d.amount)) :定义折线在 y 方向上的坐标获取方式。通过yScale比例尺将销售金额数据映射到 y 坐标。
  • svg.append('path') :在 SVG 元素中添加一个<path>元素,用于绘制折线。
  • datum(salesData) :将salesData数组绑定到<path>元素上。
  • attr('fill', 'none'):设置填充颜色为无。
  • attr('stroke', 'steelblue'):设置描边颜色为钢蓝色。
  • attr('stroke-width', 2):设置描边宽度为 2。
  • attr('d', line) :将折线生成器生成的路径描述设置给<path>元素的d属性,从而绘制出折线。

7.使用数据绘制折线和数据点

// 添加数据点

svg.selectAll('.dot')

.data(salesData)

.enter()

.append('circle')

.attr('class', 'dot')

.attr('cx', d => xScale(d.month) + 25)

.attr('cy', d => yScale(d.amount))

.attr('r', 5)

.attr('fill', 'blue');

  • svg.selectAll('.dot') :选择所有类名为.dot的元素。由于此时可能还没有这些元素,这一步主要是为后续的数据绑定和元素创建做准备。
  • data(salesData) :将salesData数据绑定到选择的元素上。如果选择的元素数量少于数据点数量,enter()方法将用于创建新的元素。
  • enter():返回一个占位符选择集,用于创建新的元素来匹配多余的数据点。
  • append('circle') :为每个多余的数据点创建一个<circle>元素。
  • attr('class', 'dot') :为创建的<circle>元素设置类名为.dot
  • attr('cx', d => xScale(d.month) + 25) :设置圆形的cx(圆心的 x 坐标)。通过xScale比例尺将数据中的月份转换为 x 坐标,并加上 25 使圆形位于坐标轴刻度中间。
  • attr('cy', d => yScale(d.amount)) :设置圆形的cy(圆心的 y 坐标)。通过yScale比例尺将数据中的销售金额转换为 y 坐标。
  • attr('r', 5):设置圆形的半径为 5。
  • attr('fill', 'blue'):设置圆形的填充颜色为蓝色。

8.监听事件并添加处理函数

// 添加提示框(简单示例,未完整实现交互)

svg.selectAll('.dot')

.on('mouseover', function (event, d) {

d3.select(this).attr('r', 8);

// 这里可以进一步完善提示框内容和样式的显示

console.log(`Month: ${d.month}, Amount: ${d.amount}`);

})

.on('mouseout', function (event, d) {

d3.select(this).attr('r', 5);

});

相关推荐
YMWM_8 分钟前
第一章 Go语言简介
开发语言·后端·golang
只因在人海中多看了你一眼9 分钟前
python语言基础
开发语言·python
2401_8582861111 分钟前
101.【C语言】数据结构之二叉树的堆实现(顺序结构) 下
c语言·开发语言·数据结构·算法·
y250812 分钟前
《Object类》
java·开发语言
小技与小术16 分钟前
数据结构之树与二叉树
开发语言·数据结构·python
旭日猎鹰34 分钟前
Flutter踩坑记录(二)-- GestureDetector+Expanded点击无效果
前端·javascript·flutter
hccee38 分钟前
C# IO文件操作
开发语言·c#
hummhumm43 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
J老熊1 小时前
JavaFX:简介、使用场景、常见问题及对比其他框架分析
java·开发语言·后端·面试·系统架构·软件工程
zmd-zk1 小时前
flink学习(2)——wordcount案例
大数据·开发语言·学习·flink