如何使用 D3.js 解析新的 Date.now() 对象以生成折线图
How to parse new Date.now() object with D3.js to generate a linechart
我正在尝试使用 D3 和 React 制作折线图,其中 x 轴基于 Date.now()
对象,所有刻度线在 10mn window.[=21 上相隔一分钟=]
- 我无法生成该行,因为我的 svg 路径中有“NaNNaNNaN”;
- 似乎无法弄清楚如何让我的 x 轴上的刻度间隔几分钟;
数据如下
// data state
data = [
{"loadAverage":0.008333333333333333,"timestamp":1632740462342},
{"loadAverage":0.008333333333333333,"timestamp":1632740459323},
{"loadAverage":0.013333333333333334,"timestamp":1632740471400}
];
timestamp
密钥是 new Date.now()
来自服务器
useEffect(() => {
const svg = d3.select(d3Container.current);
let margin = { top: 20, right: 20, bottom: 50, left: 70 },
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// set the ranges
let x = d3
.scaleTime()
.domain(d3.extent(data, (d) => timeFormat(d.timestamp)))
.range([0, width]);
let y = d3
.scaleLinear()
.domain([0, d3.max(data, (d) => d.loadAverage)])
.nice()
.range([height, 0]);
// Parse the date
let parseTime = d3.timeParse("%s");
let timeFormat = d3.timeFormat("%M:%S");
// Constructing the line
const myLine = d3
.line()
.x((d) => {
const convertedTime = parseTime(d.timestamp);
return x(convertedTime);
})
.y((d) => {
return y(d.loadAverage);
});
svg
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg
.select("svg")
.selectAll("path")
.data([data])
.join("path")
.attr("d", (value) => myLine(value))
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round");
// Add the x Axis
svg
.select("svg")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// Add the y Axis
svg
.select("svg")
.append("g")
.call(d3.axisLeft(y).tickFormat(timeFormat).ticks(10));
}, [data]);
这是我第一次使用 D3,如有任何帮助,将不胜感激!
编辑:这是我目前所做的尝试
// Constructing the line
const myLine = d3
.line()
.x((d) => {
const convertedTime = new Date(d.timestamp);
return x(convertedTime);
})
.y((d) => {
return y(d.loadAverage);
});
甚至试图 return convertedTime
像这样被 parsetime
包裹起来 parsetime(convertedTime)
也没用。
我认为您在初始化 x 比例域时遇到了问题
// set the ranges
let x = d3
.scaleTime()
// ⬇️ here is the issue, just get rid of timeFormat
.domain(d3.extent(data, (d) => timeFormat(d.timestamp)))
.range([0, width]);
scaleTime
期望域为 [Date|number, Date|number]
,您正在使用 timeFormat
,它根据给定格式将 number|Date
转换为 string
.
尝试改用它:
let x = d3
.scaleTime()
.domain(d3.extent(data, (d) => d.timestamp))
.range([0, width]);
// The short vesion
let x = d3.scaleTime(d3.extent(data, (d) => d.timestamp), [0, width])
构造线
const myLine = d3
.line()
.x((d) => x(d.timestamp))
.y((d) => y(d.loadAverage));
如果需要将时间戳转换成日期,可以映射整个数据数组
data = data.map(d=> d.timestamp = new Date(d.timestamp), d)
我正在尝试使用 D3 和 React 制作折线图,其中 x 轴基于 Date.now()
对象,所有刻度线在 10mn window.[=21 上相隔一分钟=]
- 我无法生成该行,因为我的 svg 路径中有“NaNNaNNaN”;
- 似乎无法弄清楚如何让我的 x 轴上的刻度间隔几分钟;
数据如下
// data state
data = [
{"loadAverage":0.008333333333333333,"timestamp":1632740462342},
{"loadAverage":0.008333333333333333,"timestamp":1632740459323},
{"loadAverage":0.013333333333333334,"timestamp":1632740471400}
];
timestamp
密钥是 new Date.now()
来自服务器
useEffect(() => {
const svg = d3.select(d3Container.current);
let margin = { top: 20, right: 20, bottom: 50, left: 70 },
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// set the ranges
let x = d3
.scaleTime()
.domain(d3.extent(data, (d) => timeFormat(d.timestamp)))
.range([0, width]);
let y = d3
.scaleLinear()
.domain([0, d3.max(data, (d) => d.loadAverage)])
.nice()
.range([height, 0]);
// Parse the date
let parseTime = d3.timeParse("%s");
let timeFormat = d3.timeFormat("%M:%S");
// Constructing the line
const myLine = d3
.line()
.x((d) => {
const convertedTime = parseTime(d.timestamp);
return x(convertedTime);
})
.y((d) => {
return y(d.loadAverage);
});
svg
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg
.select("svg")
.selectAll("path")
.data([data])
.join("path")
.attr("d", (value) => myLine(value))
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round");
// Add the x Axis
svg
.select("svg")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// Add the y Axis
svg
.select("svg")
.append("g")
.call(d3.axisLeft(y).tickFormat(timeFormat).ticks(10));
}, [data]);
这是我第一次使用 D3,如有任何帮助,将不胜感激!
编辑:这是我目前所做的尝试
// Constructing the line
const myLine = d3
.line()
.x((d) => {
const convertedTime = new Date(d.timestamp);
return x(convertedTime);
})
.y((d) => {
return y(d.loadAverage);
});
甚至试图 return convertedTime
像这样被 parsetime
包裹起来 parsetime(convertedTime)
也没用。
我认为您在初始化 x 比例域时遇到了问题
// set the ranges
let x = d3
.scaleTime()
// ⬇️ here is the issue, just get rid of timeFormat
.domain(d3.extent(data, (d) => timeFormat(d.timestamp)))
.range([0, width]);
scaleTime
期望域为 [Date|number, Date|number]
,您正在使用 timeFormat
,它根据给定格式将 number|Date
转换为 string
.
尝试改用它:
let x = d3
.scaleTime()
.domain(d3.extent(data, (d) => d.timestamp))
.range([0, width]);
// The short vesion
let x = d3.scaleTime(d3.extent(data, (d) => d.timestamp), [0, width])
构造线
const myLine = d3
.line()
.x((d) => x(d.timestamp))
.y((d) => y(d.loadAverage));
如果需要将时间戳转换成日期,可以映射整个数据数组
data = data.map(d=> d.timestamp = new Date(d.timestamp), d)