🎨数据可视化js库 - D3.js

D3.js 官方文档
D3.js API 文档

GeoJSON 数据集预览以及下载

GitHub

正文

D3.js (Data-Driven Documents) 是一个强大被数据驱动的js库,用于基于数据创建动态、交互式的可视化。

D3 可以接受几乎任何数字数组,字符串,或对象(本身包含其他数组或键 / 值对),可以处理 JSONGeoJSON。比如说:

js 复制代码
[
  { source: 'Microsoft', target: 'Amazon', type: 'licensing' },
  { source: 'Microsoft', target: 'HTC', type: 'licensing' },
  { source: 'Samsung', target: 'Apple', type: 'suit' },
  { source: 'Motorola', target: 'Apple', type: 'suit' },
  { source: 'Nokia', target: 'Apple', type: 'resolved' },
  { source: 'HTC', target: 'Apple', type: 'suit' },
  { source: 'Kodak', target: 'Apple', type: 'suit' },
  { source: 'Microsoft', target: 'Barnes & Noble', type: 'suit' },
  { source: 'Microsoft', target: 'Foxconn', type: 'suit' },
  ...
]

一、D3.js基础入门

1. D3.js概述与安装

D3.j通过绑定数据到DOM元素,然后根据这些数据驱动文档的变换,实现数据可视化。它结合了强大的可视化组件数据驱动的DOM操作方法。

安装方法

html 复制代码
<!-- 直接引入CDN -->
<script src="https://d3js.org/d3.v7.min.js"></script>

<!-- 或者使用npm安装 -->
npm install d3

2. 元素操作基础

D3使用类似jQuery的选择器语法来操作DOM元素:

javascript 复制代码
// 选择所有p元素并设置样式
d3.selectAll("p")
  .style("color", "blue")
  .attr("class", "highlight")
  .text("Hello D3!");

// 添加新元素
d3.select("body")
  .append("div")
  .attr("id", "new-div")
  .html("<p>This is a new div</p>");

二、数据绑定与更新

1. 数据绑定基础

D3的核心是数据绑定机制,它通过.data()方法将数据数组与DOM元素绑定:

javascript 复制代码
const dataset = [10, 20, 30, 40, 50];

// 绑定数据并创建新元素
d3.select("body").selectAll("div")
  .data(dataset)
  .enter()
  .append("div")
  .text(d => d)
  .style("height", d => d + "px");

2. 数据更新模式

D3提供了enter、update和exit三种状态处理数据变化:

javascript 复制代码
// 更新数据
const newData = [15, 25, 35];

// 选择现有元素
const bars = d3.select("body").selectAll("div").data(newData);

// 处理新增元素
bars.enter()
  .append("div")
  .text(d => d);

// 处理更新元素
bars.text(d => d);

// 处理删除元素
bars.exit().remove();

三、比例尺与坐标轴

1. 线性比例尺应用

比例尺将数据值映射到可视化空间:

javascript 复制代码
const dataset = [10, 25, 50, 100, 150, 200, 250];

// 创建线性比例尺
const xScale = d3.scaleLinear()
  .domain([0, d3.max(dataset)])  // 数据范围
  .range([0, 500]);              // 输出范围

// 使用比例尺
d3.selectAll("div")
  .style("width", d => xScale(d) + "px");

2. 坐标轴绘制

D3提供了方便的坐标轴生成器:

javascript 复制代码
// 创建坐标轴
const xAxis = d3.axisBottom(xScale)
  .ticks(5)
  .tickFormat(d => "¥" + d);

// 添加坐标轴到SVG
d3.select("svg")
  .append("g")
  .attr("transform", "translate(0, 300)")
  .call(xAxis);

四、图形生成器

1. 饼图实现

javascript 复制代码
const pie = d3.pie()
  .value(d => d.value);

const arc = d3.arc()
  .innerRadius(0)
  .outerRadius(100);

const arcs = pie([
  {value: 35, name: "A"},
  {value: 25, name: "B"},
  {value: 40, name: "C"}
]);

d3.select("svg").selectAll("path")
  .data(arcs)
  .enter()
  .append("path")
  .attr("d", arc)
  .attr("fill", (d, i) => d3.schemeCategory10[i]);

2. 折线图实现

html 复制代码
<div class="chart-container">
    <svg width="100%" height="100%"></svg>
</div>
javascript 复制代码
const line = d3.line()
  .x(d => xScale(d.date))
  .y(d => yScale(d.value))
  .curve(d3.curveBasis);

d3.select("svg")
  .append("path")
  .datum(data)
  .attr("d", line)
  .attr("fill", "none")
  .attr("stroke", "steelblue")
  .attr("stroke-width", 2);

五、交互与动画

1. 过渡动画

javascript 复制代码
d3.selectAll("circle")
  .transition()
  .duration(1000)
  .attr("r", d => d * 2)
  .attr("fill", "red")
  .transition()
  .duration(500)
  .attr("fill", "blue");

2. 拖拽交互

javascript 复制代码
const drag = d3.drag()
  .on("drag", function(event) {
    d3.select(this)
      .attr("cx", event.x)
      .attr("cy", event.y);
  });
d3.select("circle").call(drag);

中国地图实现

javascript 复制代码
// 创建投影
const projection = d3.geoMercator()
  .center([105, 38])
  .scale(800)
  .translate([width/2, height/2]);

// 创建路径生成器
const path = d3.geoPath()
  .projection(projection);

// 加载GeoJSON数据并绘制
d3.json("https://geojson.cn/api/china/1.6.2/china.topo.json").then(function(data) {
  svg.selectAll("path")
    .data(data.features)
    .enter()
    .append("path")
    .attr("d", path)
    .attr("fill", "#69b3a2")
    .attr("stroke", "#fff");
});

总结

借助SVG, Canvas 以及 HTML一些dom去把json一些数据根据一些图形展示出来。

官网有现成的例子,可以直接拿来用。借助SVG, Canvas 以及 HTML一些dom去把json一些数据根据一些图形展示出来。

一开始有时候有人看到这种很多很奇特的图形效果,很容易被吓住,觉得自己一定搞不赢。其实很多时候是数据的变动和不同,再结合人家已经写好的封装好的东西,再具体情况具体分析去一步步做出来的。

相关推荐
Qrun4 小时前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp4 小时前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.5 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl7 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫9 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友9 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理11 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻11 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
mapbar_front12 小时前
在职场生存中如何做个不好惹的人
前端
牧杉-惊蛰12 小时前
纯flex布局来写瀑布流
前端·javascript·css