如何使用D3.js结合给定JSON支付数据自定义实现目标样式点状图
D3 点状支付状态图实现方案
1. 核心实现思路
- 把原始数据的日期字符串转换为JavaScript日期对象,方便时间比例尺计算
- 为三种支付状态配置差异化的颜色映射,视觉上直接区分状态
- X轴使用时间比例尺映射日期范围,Y轴固定位置即可实现单行点状展示,如有多维度分组需求可扩展Y轴比例尺
- 按需添加坐标轴提示、圆点hover交互增强可读性
2. 完整实现代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- 本地引入D3 v7版本即可,也可替换为你本地的D3依赖路径 --> <script src="https://d3js.org/d3.v7.min.js"></script> <style> .axis text { font-size: 12px; } .dot { stroke: #fff; stroke-width: 1px; } </style> </head> <body> <svg id="chart" width="800" height="150"></svg> <script> // 示例数据,可替换为你的真实JSON数据源 const rawData = [ {"date": "2020.12.1", "pay": 1}, {"date": "2021.1.2", "pay": 2}, {"date": "2021.2.1", "pay": 3}, {"date": "2021.3.5", "pay": 1}, {"date": "2021.4.10", "pay": 2}, {"date": "2021.5.3", "pay": 1} ]; // 数据预处理:转换日期格式 const data = rawData.map(d => ({ date: d3.timeParse("%Y.%m.%d")(d.date), pay: d.pay })); // 画布边距设置 const margin = {top: 20, right: 20, bottom: 30, left: 40}; const width = 800 - margin.left - margin.right; const height = 150 - margin.top - margin.bottom; const svg = d3.select("#chart") .append("g") .attr("transform", `translate(${margin.left},${margin.top})`); // 颜色映射 const colorMap = { 1: "#2ecc71", // 按时支付-绿色 2: "#e74c3c", // 逾期未支付-红色 3: "#95a5a6" // 无数据-灰色 }; // X轴时间比例尺 const xScale = d3.scaleTime() .domain(d3.extent(data, d => d.date)) .range([0, width]); // 绘制X轴 svg.append("g") .attr("transform", `translate(0,${height/2})`) .call(d3.axisBottom(xScale) .ticks(d3.timeMonth.every(1)) .tickFormat(d3.timeFormat("%Y.%m")) ) .attr("class", "axis"); // 绘制圆点 svg.selectAll(".dot") .data(data) .enter() .append("circle") .attr("class", "dot") .attr("cx", d => xScale(d.date)) .attr("cy", height/2) .attr("r", 6) .attr("fill", d => colorMap[d.pay]); </script> </body> </html>
3. 自定义调整说明
- 如需调整圆点大小,修改
attr("r", 6)里的数值即可 - 如需修改状态对应的颜色,调整
colorMap里的色值即可 - 如需增加hover显示具体日期和状态的效果,可以在绘制圆点的代码后添加
on事件绑定交互逻辑 - 如果数据跨度更长,可以调整X轴的
ticks配置,改为每2个月或每季度显示一个刻度避免文字重叠
内容的提问来源于stack exchange,提问作者programer
相关产品推荐
相关产品推荐

