利用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);

});

相关推荐
猷咪6 分钟前
C++基础
开发语言·c++
IT·小灰灰7 分钟前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧9 分钟前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q10 分钟前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳010 分钟前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾10 分钟前
php 对接deepseek
android·开发语言·php
2601_9498683614 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
摘星编程19 分钟前
React Native + OpenHarmony:UniversalLink通用链接
javascript·react native·react.js
星火开发设计28 分钟前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识
qq_1777673740 分钟前
React Native鸿蒙跨平台数据使用监控应用技术,通过setInterval每5秒更新一次数据使用情况和套餐使用情况,模拟了真实应用中的数据监控场景
开发语言·前端·javascript·react native·react.js·ecmascript·harmonyos