我正在嘗試通過 useEffect 狀態將資料從 csv 加載到 useState 中。但我無法讓它作業。
我的 csv 包含這樣的資料:
Date Value1 Value2
2020/7/20 1 4
2020/7/21 2 8
2020/7/22 3 10
2020/7/23 4 12
2020/7/24 5 67
2020/7/25 6 10
我試圖useState通過useEffect這樣的方式獲取資料:
import * as d3 from 'd3';
import {useEffect, useState} from 'react';
import csvFile from '../data/Data.csv';
const Linechart = (props) => {
const [data, setData] = useState([]);
useEffect(()=>{
if (data.length > 0) {
drawChart();
} else {
getCSVData();
}
,[]);
// gets csv data from csv
const getCSVData = async () => {
let tempData = [];
await d3.csv(csvFile,
function(d){
tempData.push({date: d3.timeParse("%Y/%m/%d")(d.Date), value1: parseFloat(d.Value1), value2: parseFloat(d.Value2)}),
}
)
setData(tempData);
console.log("data is: ", data.date)
console.log("value1 is: ", data.value1)
console.log("value2 is: ", data.value2)
}
由于某種原因,它不想作業。我收到以下錯誤:
attr.js:30 Error: <path> attribute d: Expected number, "MNaN,NaNLNaN,NaNL…".
它似乎卡在tempData.push. 我從來沒有使用過這個.push(我對 React 和 Javascript 都很陌生)。有人可以幫我解決這個問題嗎?
資料用于 d3 可視化,這是創建折線圖的完整代碼:
import * as d3 from 'd3';
import {useEffect, useState} from 'react';
import csvFile from '../data/Data.csv';
const Linechart = (props) => {
const [data, setData] = useState([]);
const {width, height } = props;
useEffect(()=>{
if (data.length > 0) {
drawChart();
} else {
getCSVData();
}},[data]);
console.log(data)
// gets csv data from a csv
const getCSVData = async () => {
let tempData = [];
await d3.csv(csvFile,
function(d){
tempData.push({date: d3.timeParse("%m/%d/%Y")(d.Date), value1: parseFloat(d.Value1), value2: parseFloat(d.Value2)});
}
)
console.log(tempData)
setData(tempData);
console.log("data is: ",data.date)
}
const drawChart = () => {
// create the chart area
const svg = d3.select('.svg-canvas')
svg.selectAll("*").remove();
// Add X axis --> it is a date format
var x = d3.scaleTime()
.domain(d3.csv(data, function(d) { return d.date; }))
.range([ 0, width ]);
svg.append("g")
.attr("transform", "translate(0," height ")")
.call(d3.axisBottom(x));
// Add Y axis
var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return d.value1; })])
.range([ height, 0 ]);
svg.append("g")
.call(d3.axisLeft(y));
// set line coordinates
const line = d3.line()
.x(function(d) { return x(d.date) })
.y(function(d) { return y(d.value1) })
// Add the line
svg.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("d", line)
}
return (
<div>
<svg className="svg-canvas" width="1000px" height="600px" />
</div>
)
}
export default Linechart;
錯誤來自drawChart函式,因為它沒有接收到正確的資料
uj5u.com熱心網友回復:
您不能那樣使用.push(),您需要將所有值包裝在一個物件中,然后將它們推送到tempData陣列中。之后,您將能夠使用新陣列設定狀態。
tempData.push( { date: d3.timeParse("%Y/%m/%d")(d.Date), value1: parseFloat(d.Value1), value2: parseFloat(d.Value2) } );
setData(tempData);
現在您將擁有狀態,該狀態將成為陣列,其中 0 索引上的一項將成為具有屬性的物件。
[ 0: { date: ... , value1: ... , value2: ... } ]
之后,當您需要訪問資料時,您必須遍歷陣列。
data.map((currentEl) => {
console.log(currentEl)
console.log(currentEl.date)
console.log(currentEl.value1)
console.log(currentEl.value2)
})
另一種方法是將你的狀態設定為物件,
const [data, setData] = useState({date: '', value1: '', value2: ''});
const tempData = { date: d3.timeParse("%Y/%m/%d")(d.Date), value1: parseFloat(d.Value1), value2: parseFloat(d.Value2) }
setData(tempData);
console.log(data.date)
console.log(data.value1)
console.log(data.value2)
uj5u.com熱心網友回復:
您的資料和決議方式都有問題。
- 資料不是逗號分隔的。
- 您嘗試使用的日期格式具有相反順序的單位,并且日期不是零填充的。
資料實際上應該使用逗號分隔的列:
資料.csv
Date,Value1,Value2
2020/7/20,1,4
2020/7/21,2,8
2020/7/22,3,10
2020/7/23,4,12
2020/7/24,5,67
2020/7/25,6,10
確保每行末尾也沒有尾隨空格。
您應該用來決議日期的格式是"%Y/%m/%d".
const getCSVData = async () => {
const tempData = [];
await d3.csv(
csvFile,
function (d) {
tempData.push({
date: d3.timeParse("%Y/%m/%d")(d.Date),
value1: Number(d.Value1),
value2: Number(d.Value2)
});
}
);
setData(tempData);
};

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/511497.html
上一篇:路徑質心計算
