d3.js绘制多折线图报path d属性期望M/m命令错误排查
问题报错
使用D3.js v5绘制多折线图时,控制台抛出源自d3.v5.min.js:2的错误:
Error: <path> attribute d: Expected moveto path command ('M' or 'm'), "function t(t){va…".
错误原因
代码存在3处核心问题,直接导致路径渲染失败:
- 折线生成逻辑错误:
d3.line()是路径生成器函数,你只配置了x、y访问规则,没有传入分组数据执行生成器,最终给<path>的d属性赋值的是函数本身,而非生成的路径字符串,这是触发该报错的直接原因 - 时间字段处理API用错:误用
d3.timeFormat将时间对象转为格式化字符串,没有保留可用于比例尺计算的Date对象/时间戳 - X轴比例尺选型错误:时间维度数据应使用
d3.scaleTime,你用了线性比例尺d3.scaleLinear搭配格式化后的时间字符串,会导致坐标计算完全失效;另外d3.nest()分组后每个分组的点数据存在values字段下,代码未读取该字段。
修复方案
将对应代码段替换为如下逻辑即可:
// 修正时间处理:用timeParse将原始时间字符串转为Date对象,不要提前转成格式化字符串 // 若原始d.ts已经是Date对象/时间戳,可跳过解析步骤 const dateParser = d3.timeParse("%Y-%m-%d %H:%M:%S"); data.forEach(function(d) { d.ts = dateParser(d.ts); d.value = parseFloat(d.value) }); // 其余SVG初始化、nest分组、Y轴、色板逻辑保持不变,仅替换X轴定义 var x = d3.scaleTime() .domain(d3.extent(data, function(d) { return d.ts; })) .range([ 0, width ]); svg.append("g") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x).ticks(5)); // 替换折线绘制逻辑 svg.selectAll(".line") .data(sumstat) .enter() .append("path") .attr("fill", "none") .attr("stroke", function(d){ return color(d.key) }) .attr("stroke-width", 1.5) .attr("d", function(d){ // 配置路径生成器 const lineGenerator = d3.line() .x(function(point) { return x(point.ts); }) .y(function(point) { return y(point.value); }) // 传入当前分组的点数组,生成合法路径字符串 return lineGenerator(d.values); })
注意事项
d3.line()生成器必须传入点数组才会返回合法的SVG路径字符串,直接返回生成器函数本身就会触发你遇到的报错- 如果你的原始时间字段格式和
%Y-%m-%d %H:%M:%S不匹配,需要对应调整d3.timeParse的格式占位符,保证解析后得到合法的Date对象 d3.nest()分组返回的结构为{key: 分组标识, values: [该分组下所有数据点]},所有分组级别的数据操作都要读取values字段获取点列表
内容的提问来源于stack exchange,提问作者alex acquier
相关产品推荐
相关产品推荐

