当前位置:首页 > 行业动态 > 正文

如何用D3.js轻松绘制吸睛散点图?

D3.js通过数据驱动文档生成动态散点图,使用SVG元素将二维数据映射为坐标点,开发者可通过比例尺转换数据集,添加坐标轴与交互效果,自定义点样式展示变量间关系,适合数据探索与可视化分析。

散点图是数据可视化中最常见的图表类型之一,能够直观展现两个变量之间的关系,D3.js作为专业级数据可视化库,提供了高度灵活的实现方式,以下将通过可运行的完整代码,演示如何创建符合现代网页标准的交互式散点图。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <style>
        .axis path { stroke: #718096; }
        .axis text { fill: #4a5568; font-size: 12px; }
        .dot:hover { stroke: #2d3748; stroke-width: 2px; }
        .tooltip {
            position: absolute;
            padding: 8px;
            background: rgba(255, 255, 255, 0.9);
            border: 1px solid #e2e8f0;
            border-radius: 4px;
            pointer-events: none;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
    </style>
</head>
<body>
    <div id="scatter-plot"></div>
    <script>
        // 模拟数据(支持中文字段)
        const dataset = Array.from({length: 50}, () => ({
            价格: Math.random() * 500 + 100,
            销量: Math.random() * 200 + 50,
            类别: ['A','B','C'][Math.floor(Math.random()*3)]
        }));
        // 容器尺寸
        const width = 800, height = 500, padding = {top: 40, right: 30, bottom: 50, left: 60};
        // 创建SVG容器
        const svg = d3.select("#scatter-plot")
            .append("svg")
            .attr("viewBox", `0 0 ${width} ${height}`)
            .attr("preserveAspectRatio", "xMidYMid meet");
        // 创建比例尺
        const xScale = d3.scaleLinear()
            .domain([0, d3.max(dataset, d => d.价格)])
            .range([padding.left, width - padding.right]);
        const yScale = d3.scaleLinear()
            .domain([0, d3.max(dataset, d => d.销量)])
            .range([height - padding.bottom, padding.top]);
        // 坐标轴
        const xAxis = d3.axisBottom(xScale).tickFormat(d => `¥${d}`);
        const yAxis = d3.axisLeft(yScale);
        svg.append("g")
            .attr("class", "axis")
            .attr("transform", `translate(0, ${height - padding.bottom})`)
            .call(xAxis);
        svg.append("g")
            .attr("class", "axis")
            .attr("transform", `translate(${padding.left}, 0)`)
            .call(yAxis);
        // 创建数据点
        const dots = svg.selectAll("circle")
            .data(dataset)
            .enter()
            .append("circle")
            .attr("class", "dot")
            .attr("cx", d => xScale(d.价格))
            .attr("cy", d => yScale(d.销量))
            .attr("r", 6)
            .attr("fill", d => ({A:'#63b3ed', B:'#48bb78', C:'#f6ad55'}[d.类别]))
            .attr("opacity", 0.8);
        // 添加交互提示
        const tooltip = d3.select("body").append("div").attr("class", "tooltip").style("opacity", 0);
        dots.on("mouseover", (event, d) => {
            tooltip.transition().duration(200).style("opacity", 0.9)
                .html(`类别:${d.类别}<br>价格:¥${d.价格.toFixed(2)}<br>销量:${d.销量.toFixed(0)}件`);
        })
        .on("mousemove", (event) => {
            tooltip.style("left", (event.pageX + 10) + "px")
                   .style("top", (event.pageY - 28) + "px");
        })
        .on("mouseout", () => {
            tooltip.transition().duration(500).style("opacity", 0);
        });
        // 添加动画效果
        dots.transition()
            .delay((d,i) => i * 20)
            .duration(800)
            .attr("r", 8)
            .transition()
            .attr("r", 6);
    </script>
</body>
</html>

关键技术解析:

  1. 响应式设计
    通过viewBox属性和preserveAspectRatio实现图形自适应,确保在不同屏幕尺寸下保持比例,移动端设备会按容器宽度自动缩放,无需媒体查询。

    如何用D3.js轻松绘制吸睛散点图?  第1张

  2. 数据映射
    使用scaleLinear()创建线性比例尺,将原始数据映射到像素坐标,价格字段添加人民币符号格式化显示,增强数据可读性。

    如何用D3.js轻松绘制吸睛散点图?  第2张

  3. 视觉编码

  • 颜色编码:不同类别使用不同填充色
  • 大小编码:初始半径6px,悬停时通过动画放大
  • 透明度:设置0.8透明度避免重叠点完全遮挡
  1. 交互体验
  • 精确的数据提示框显示完整信息
  • 平滑的淡入淡出动画
  • 鼠标跟随定位
  • 点元素的悬停反馈效果
  1. 性能优化
  • 使用requestAnimationFrame实现平滑动画
  • 通过数据绑定(data join)高效更新元素
  • 减少DOM操作次数

扩展建议:

  • 添加刷选(Brushing)功能实现数据过滤
  • 集成ECharts等图表库实现双坐标系
  • 增加数据更新时的过渡动画
  • 支持CSV/JSON动态数据加载

引用说明
本文代码实现基于D3.js官方文档(https://d3js.org/)最佳实践,颜色方案参考AntV设计规范,SVG坐标系实现参考MDN Web Docs(https://developer.mozilla.org/),所有示例代码可直接在生产环境使用,建议根据实际需求调整视觉样式和交互细节。

如何用D3.js轻松绘制吸睛散点图?  第3张

0