Error: <path> attribute d: Expected number, "MNaN,36.393574100…
Error: <path> attribute d: Expected number, "MNaN,36.393574100…
我正在尝试使用 d3.js 构建一个简单的折线图并将其呈现在反应组件中。不幸的是,我收到以下错误:
Error: <path> attribute d: Expected number, "MNaN,36.393574100…"
不幸的是Whosebug的类似问题对我帮助不大。我的理论是,当我将路径附加到图表时,我没有正确读取数据对象 (data.forEach) 到我的“d”属性。我已经尝试使用和不使用 parseDate 函数来执行此操作。当我在没有它的情况下这样做时,我的日期看起来应该如何在控制台中显示。如果我稍后在代码中包含 parseDate 函数,同时我在路径 d 属性的 x 函数中声明我的 x 轴 and/or ......没有什么真正改变。我也不完全确定我的数据对象是否正确嵌套,或者我是否应该将整个数据对象提供给 datum() 函数....
这是我的代码:
import * as d3 from "d3";
import React, { useRef, useEffect } from "react";
function LineBarChart({ width, height, data }) {
const ref = useRef();
useEffect(() => {
d3.select(ref.current)
.attr("width", width)
.attr("height", height)
// .style("border", "1px solid black");
}, [height, width]);
useEffect(() => {
draw();
}, [data]);
const draw = () => {
const parseDate = d3.timeFormat("%Y-%m-%d");
data.forEach(function (d) {
d.dateM = d.dateM;
// d.dateM = parseDate(d.dateM);
d.closeM = +d.closeM;
console.log("WHAT-DO-I-LOOK-LIKE", d.dateM)
});
// const dataNest = d3.nest()
// .key((d) => d.dateM)
// .key((d) => d.closeM)
// .map(data);
const margin = 80;
const width = 1400 - 2 * margin;
const height = 800 - 2 * margin;
const svg = d3.select(ref.current);
const chart = svg
.append("g")
.attr("class", "linechart")
.attr("transform", `translate(${margin}, ${margin})`);
var x = d3.scaleTime()
.domain(d3.extent(data, function(d) { return d.dateM; }))
//.domain(d3.extent(data, function(d) { return parseDate(d.dateM); }))
.range([ 0, width ]);
chart.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return +d.closeM; })])
.range([ height, 0 ]);
chart.append("g")
.call(d3.axisLeft(y));
chart.append("path")
.datum(data)
.attr('class', 'lineChartClass')
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("d", d3.line()
// .x(function(d) { return parseDate(d.dateM) })
.x(function(d) { return x(d.dateM) })
.y(function(d) { return y(d.closeM) })
)
}; //draw
return (
<div className="chartSixPointFive">
<svg ref={ref}></svg>
</div>
);
}
export default LineBarChart;
我的 React 应用程序使用 Axios 来访问 Flask 端点。这里没有什么特别的,我只是 return 这样的线图。
....
....
<LineBarChart width={1350} height={1000} data={data} />
如有必要,我可以包含完整的 React 代码(尽管我认为不需要)
这是我的数据对象的样子:
"results": [
{
"date": "2022-02-07",
"open": 172.860001,
"high": 173.949997,
"low": 170.949997,
"close": 171.660004,
"volume": 77045100,
"adjClose": 171.660004
},
rinse & repeat ....
]
我很感激能得到的任何帮助!
d3.timeFormat
格式化日期对象和 returns 一个 字符串 。你想要的是 d3.timeParse
相反,它会做相反的事情:它将你的字符串解析为日期对象,可以由时间尺度使用:
const parseDate = d3.timeParse("%Y-%m-%d");
PS:"d" 属性的 M 命令使用(几乎所有语言中的所有内容)坐标对 x,y
(horizontal/vertical)。因此,当您遇到错误时:
MNaN,42...
...您知道问题出在您的 x 刻度上,而错误:
M42,NaN...
...显示问题出在 y 尺度上。
我正在尝试使用 d3.js 构建一个简单的折线图并将其呈现在反应组件中。不幸的是,我收到以下错误:
Error: <path> attribute d: Expected number, "MNaN,36.393574100…"
不幸的是Whosebug的类似问题对我帮助不大。我的理论是,当我将路径附加到图表时,我没有正确读取数据对象 (data.forEach) 到我的“d”属性。我已经尝试使用和不使用 parseDate 函数来执行此操作。当我在没有它的情况下这样做时,我的日期看起来应该如何在控制台中显示。如果我稍后在代码中包含 parseDate 函数,同时我在路径 d 属性的 x 函数中声明我的 x 轴 and/or ......没有什么真正改变。我也不完全确定我的数据对象是否正确嵌套,或者我是否应该将整个数据对象提供给 datum() 函数....
这是我的代码:
import * as d3 from "d3";
import React, { useRef, useEffect } from "react";
function LineBarChart({ width, height, data }) {
const ref = useRef();
useEffect(() => {
d3.select(ref.current)
.attr("width", width)
.attr("height", height)
// .style("border", "1px solid black");
}, [height, width]);
useEffect(() => {
draw();
}, [data]);
const draw = () => {
const parseDate = d3.timeFormat("%Y-%m-%d");
data.forEach(function (d) {
d.dateM = d.dateM;
// d.dateM = parseDate(d.dateM);
d.closeM = +d.closeM;
console.log("WHAT-DO-I-LOOK-LIKE", d.dateM)
});
// const dataNest = d3.nest()
// .key((d) => d.dateM)
// .key((d) => d.closeM)
// .map(data);
const margin = 80;
const width = 1400 - 2 * margin;
const height = 800 - 2 * margin;
const svg = d3.select(ref.current);
const chart = svg
.append("g")
.attr("class", "linechart")
.attr("transform", `translate(${margin}, ${margin})`);
var x = d3.scaleTime()
.domain(d3.extent(data, function(d) { return d.dateM; }))
//.domain(d3.extent(data, function(d) { return parseDate(d.dateM); }))
.range([ 0, width ]);
chart.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return +d.closeM; })])
.range([ height, 0 ]);
chart.append("g")
.call(d3.axisLeft(y));
chart.append("path")
.datum(data)
.attr('class', 'lineChartClass')
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("d", d3.line()
// .x(function(d) { return parseDate(d.dateM) })
.x(function(d) { return x(d.dateM) })
.y(function(d) { return y(d.closeM) })
)
}; //draw
return (
<div className="chartSixPointFive">
<svg ref={ref}></svg>
</div>
);
}
export default LineBarChart;
我的 React 应用程序使用 Axios 来访问 Flask 端点。这里没有什么特别的,我只是 return 这样的线图。
....
....
<LineBarChart width={1350} height={1000} data={data} />
如有必要,我可以包含完整的 React 代码(尽管我认为不需要)
这是我的数据对象的样子:
"results": [
{
"date": "2022-02-07",
"open": 172.860001,
"high": 173.949997,
"low": 170.949997,
"close": 171.660004,
"volume": 77045100,
"adjClose": 171.660004
},
rinse & repeat ....
]
我很感激能得到的任何帮助!
d3.timeFormat
格式化日期对象和 returns 一个 字符串 。你想要的是 d3.timeParse
相反,它会做相反的事情:它将你的字符串解析为日期对象,可以由时间尺度使用:
const parseDate = d3.timeParse("%Y-%m-%d");
PS:"d" 属性的 M 命令使用(几乎所有语言中的所有内容)坐标对 x,y
(horizontal/vertical)。因此,当您遇到错误时:
MNaN,42...
...您知道问题出在您的 x 刻度上,而错误:
M42,NaN...
...显示问题出在 y 尺度上。