D3.js实战:数据可视化高级技巧实例应用

server/2024/9/24 16:26:59/

基础

首先,我们需要一个HTML文件来引入D3.js库,并准备一个画布来放置我们的图表。

<!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><script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body><svg width="500" height="500"></svg>
</body>
</html>

创建简单的线图

// 假设我们有以下数据
var data = [4, 8, 15, 16, 23, 42];// 创建SVG画布
var svg = d3.select("svg"),margin = {top: 20, right: 20, bottom: 30, left: 50},width = +svg.attr("width") - margin.left - margin.right,height = +svg.attr("height") - margin.top - margin.bottom;// 创建x和y比例尺
var x = d3.scaleLinear().domain(d3.extent(data, d => d)).range([0, width]);var y = d3.scaleLinear().domain([0, d3.max(data)]).range([height, 0]);// 创建x和y轴
var xAxis = d3.axisBottom(x),yAxis = d3.axisLeft(y);// 添加轴
svg.append("g").attr("transform", "translate(0," + height + ")").call(xAxis);svg.append("g").call(yAxis);// 绘制折线
var line = d3.line().x(d => x(d)).y(d => y(d));svg.append("path").datum(data).attr("class", "line").attr("d", line);

创建柱状图

// 假设我们有以下数据
var data = [4, 8, 15, 16, 23, 42];// 创建SVG画布和比例尺
var svg = d3.select("svg").attr("width", 500).attr("height", 500);
var margin = {top: 20, right: 20, bottom: 30, left: 40};
var width = +svg.attr("width") - margin.left - margin.right;
var height = +svg.attr("height") - margin.top - margin.bottom;
var x = d3.scaleBand().rangeRound([0, width]).padding(0.1);
var y = d3.scaleLinear().rangeRound([height, 0]);// 数据映射到比例尺
x.domain(data.map(function(d) { return d; }));
y.domain([0, d3.max(data)]);// 创建SVG g元素
var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");// 添加x和y轴
g.append("g").attr("transform", "translate(0," + height + ")").call(d3.axisBottom(x));g.append("g").call(d3.axisLeft(y));// 绘制柱状图
g.selectAll(".bar").data(data).enter().append("rect").attr("class", "bar").attr("x", function(d) { return x(d); }).attr("y", function(d) { return y(d); }).attr("width", x.bandwidth()).attr("height", function(d) { return height - y(d); });

创建饼图

// 假设我们有以下数据
var data = [4, 8, 15, 16, 23, 42];// 创建SVG画布和比例尺
var svg = d3.select("svg").attr("width", 500).attr("height", 500);
var radius = Math.min(svg.attr("width"), svg.attr("height")) / 2;// 创建弧度比例尺
var arc = d3.arc().outerRadius(radius).innerRadius(0);
var pie = d3.pie().value(function(d) { return d; });// 绘制饼图
var g = svg.append("g").attr("transform", "translate(" + radius + "," + radius + ")");var arcs = g.selectAll("arc").data(pie(data)).enter().append("g").attr("class", "arc");arcs.append("path").attr("d", arc).attr("fill", function(d, i) { return d3.schemeCategory10[i]; });arcs.append("text").attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; }).attr("dy", ".35em").text(function(d) { return d.data; });

交互性与动画

交互性示例:添加悬停效果到柱状图

// 假设已有柱状图基础代码
// ...// 添加悬停效果
g.selectAll(".bar").on("mouseover", function(event, d) {d3.select(this).transition().duration(200).attr("fill", "orange"); // 鼠标悬停颜色变化// 显示数据提示var tooltip = g.append("text").attr("class", "tooltip").attr("x", x(d) + x.bandwidth() / 2).attr("y", y(d) - 10).text(d);}).on("mouseout", function(event, d) {d3.select(this).transition().duration(200).attr("fill", "steelblue"); // 恢复原始颜色// 移除数据提示g.selectAll(".tooltip").remove();});

动画示例:平滑过渡线图数据更新

// 假设已有线图基础代码
// ...// 更新数据
var newData = [8, 15, 16, 23, 42, 45];// 更新比例尺域
x.domain(d3.extent(newData));
y.domain([0, d3.max(newData)]);// 更新轴
g.select(".axis--x").transition().duration(750).call(xAxis);
g.select(".axis--y").transition().duration(750).call(yAxis);// 更新路径
var path = g.select(".line");
path.datum(newData).transition().duration(750).attr("d", line);

复杂图表:力导向图

力导向图展示节点和边的关系,非常适合网络、社交图谱等数据的可视化。

// 假设我们有节点和边的数据
var nodes = [{id: "A"}, {id: "B"}, {id: "C"}];
var links = [{source: nodes[0], target: nodes[1]}, {source: nodes[1], target: nodes[2]}];// 创建SVG画布
var svg = d3.select("svg"),width = +svg.attr("width"),height = +svg.attr("height");// 创建力模拟
var simulation = d3.forceSimulation(nodes).force("link", d3.forceLink(links).id(function(d) { return d.id; })).force("charge", d3.forceManyBody()).force("center", d3.forceCenter(width / 2, height / 2));// 创建链接和节点
var link = svg.append("g").attr("stroke", "#999").attr("stroke-opacity", 0.6).selectAll("line").data(links).join("line").attr("stroke-width", 2);var node = svg.append("g").attr("stroke", "#fff").attr("stroke-width", 1.5).selectAll("circle").data(nodes).join("circle").attr("r", 5).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));node.append("title").text(function(d) { return d.id; });simulation.on("tick", ticked);function ticked() {link.attr("x1", function(d) { return d.source.x; }).attr("y1", function(d) { return d.source.y; }).attr("x2", function(d) { return d.target.x; }).attr("y2", function(d) { return d.target.y; });node.attr("cx", function(d) { return d.x; }).attr("cy", function(d) { return d.y; });
}// 拖拽事件处理函数
function dragstarted(event, d) {if (!event.active) simulation.alphaTarget(0.3).restart();d.fx = d.x;d.fy = d.y;
}function dragged(event, d) {d.fx = event.x;d.fy = event.y;
}function dragended(event, d) {if (!event.active) simulation.alphaTarget(0);d.fx = null;d.fy = null;
}

地图可视化

D3.js可以与地理数据格式如GeoJSON配合,创建互动式地图。这包括国家、州、城市边界等。

基本步骤:

  • 加载地图数据:使用D3的d3.json或d3.geoJson加载GeoJSON数据。
  • 创建比例尺:定义地理投影和比例尺,如Mercator或Albers USA。
  • 绑定数据并绘制:将GeoJSON数据绑定到SVG路径元素,并应用投影。
  • 添加交互:如悬停效果、点击事件等。
d3.json("world.geojson").then(function(geoData) {var svg = d3.select("svg"),projection = d3.geoMercator().scale(130).translate([400, 250]),path = d3.geoPath().projection(projection);svg.selectAll("path").data(geoData.features).enter().append("path").attr("d", path).attr("fill", "#ccc").attr("stroke", "#fff");
});

数据绑定与动态更新

基本步骤:

  • 初始化数据绑定:使用data()方法绑定数据到DOM元素。
  • Enter, Update, Exit模式:处理新数据、更新现有数据及移除无用数据。
  • 动态更新:监听数据变化,重新执行绑定和渲染流程。
var svg = d3.select("svg"),data = [4, 8, 15, 16, 23, 42];// 初始化柱状图
var bars = svg.selectAll("rect").data(data);bars.enter().append("rect").attr("x", function(d, i) { return i * 50; }).attr("y", function(d) { return 300 - d; }).attr("width", 40).attr("height", function(d) { return d; });// 动态更新
setInterval(function() {data = data.map(function(d) { return Math.max(0, Math.random() * 50); });bars.data(data).transition().duration(500).attr("y", function(d) { return 300 - d; }).attr("height", function(d) { return d; });
}, 2000);

复杂图表与高级技巧

高级技巧:

  • 使用D3的组件库:像D3fc这样的库提供了高级图表组件,简化复杂图表的创建。
  • 动画与过渡:利用transition()方法创建流畅的动画效果。
  • 交互性:增加点击、悬停事件,使用brush和zoom功能增强用户体验。
  • 性能优化:合理使用selectAll(), data(), enter(), exit()减少DOM操作,使用requestAnimationFrame()优化动画性能。

2024年礼包2500G计算机入门到高级架构师开发资料超级大礼包免费送!


http://www.ppmy.cn/server/39684.html

相关文章

AI时代:低代码与人工智能引领科技创造新时代

随着科技的飞速发展&#xff0c;我们步入了一个崭新的时代——AI时代。在这个时代&#xff0c;低代码和人工智能技术如日中天&#xff0c;成为引领科技创造的新引擎。本文将围绕这一主题&#xff0c;探讨低代码和人工智能如何在各个领域发挥巨大作用&#xff0c;推动科技创造迈…

常用的 Ansible 模块

以下是一些常用的 Ansible 模块&#xff1a; - ping 模块&#xff1a;用于检测目标主机是否可达。 - file 模块&#xff1a;可以管理文件和目录&#xff0c;如创建、删除、修改权限等。 - copy 模块&#xff1a;用于将本地文件复制到远程主机。 - service 模块&#xff1a;管…

HIVE函数的基本使用

HIVE函数的基本使用 1.查看所有支持的函数 共289个 1)SHOW FUNCTIONS 查看所有支持的函数 共289个 2)SHOW FUNCTIONS LIKE "**" 模糊查询函数名 3)DESC FUNCTION 函数名 可以查看函数的具体使用方法 show functions; show functions like "*c…

Android 14 变更及适配攻略

准备工作 首先将我们项目中的 targetSdkVersion和compileSdkVersion 升至 34。 影响Android 14上所有应用 1.最低可安装的目标 API 级别 从 Android 14 开始&#xff0c;targetSdkVersion 低于 23 的应用无法安装。要求应用满足这些最低目标 API 级别要求有助于提高用户的安…

【R语言从0到精通】-4-回归建模

通过之前的文章&#xff0c;我们已经基本掌握了R语言的基本使用方法&#xff0c;那从本次教程开始&#xff0c;我们开始聚焦如何使用R语言进行回归建模。 4.1 回归简介 回归分析是一种统计学方法&#xff0c;用于研究两个或多个变量之间的相互关系和依赖程度。它可以帮助我们了…

conda删除虚拟环境命令

conda删除虚拟环境命令 删除虚拟环境的命令可以使用conda命令的remove或者env remove子命令&#xff0c;具体的实现方法如下所示&#xff1a; 使用conda remove命令删除虚拟环境&#xff1a; conda remove --name <环境名称> --all 这将删除指定名称的虚拟环境…

2024数维杯数学建模竞赛A题完整代码和思路论文解析

2024数维杯数学建模完整代码和成品论文已更新&#xff0c;获取↓↓↓↓↓ https://www.yuque.com/u42168770/qv6z0d/bgic2nbxs2h41pvt?singleDoc# 2024数维杯数学建模A题34页论文已完成&#xff0c;论文包括摘要、问题重述、问题分析、模型假设、符号说明、模型的建立和求解&…

Java虚拟机(JVM)中确保资源及时释放的策略

在Java虚拟机&#xff08;JVM&#xff09;中&#xff0c;内存管理主要是通过垃圾回收&#xff08;Garbage Collection, GC&#xff09;来自动处理的。Java开发者通常不需要&#xff08;也不应该&#xff09;显式地释放对象内存&#xff0c;因为JVM的垃圾回收器会自动处理不再使…