首先,我们需要一个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.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");
});
基本步骤:
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);
高级技巧:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。