我想使用 d3.js 显示温度和湿度曲线,但是我的代码运行时使用了这个错误的折线图,为什么会有黑色区域?我的代码有什么问题吗?有人能帮我吗?欣赏它。
数据是从CSV文件中读取的,解析数据后,我绘制折线图来显示温度和湿度线,但它有一些问题。
我尝试画平滑的线。
<script src="https://d3js.org/d3.v6.min.js"></script>
// 定义SVG画布大小
const margin = {
top: 20,
right: 30,
bottom: 30,
left: 40
};
const width = 800 - margin.left - margin.right;
const height = 400 - margin.top - margin.bottom;
// 创建SVG元素
const svg = d3.select("#chart")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
// 解析CSV数据
d3.csv("data.csv").then((data) => {
// 解析时间并创建时间刻度
const parseTime = d3.timeParse("%Y-%m-%d %H:%M:%S");
data.forEach((d) => {
d.time = parseTime(d.time);
});
// 创建x轴和y轴比例尺
const xScale = d3.scaleTime()
.domain(d3.extent(data, (d) => d.time)) // 输入域为时间范围
.range([0, width]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(data, (d) => d.value)]) // 输入域为数据范围
.range([height, 0]);
// 创建温度和湿度数据的线性插值器
const temperatureLine = d3.line()
.x((d) => xScale(d.time))
.y((d) => yScale(d.value))
.curve(d3.curveCardinal); // 平滑曲线
const humidityLine = d3.line()
.x((d) => xScale(d.time))
.y((d) => yScale(d.value))
.curve(d3.curveCardinal);
// 创建x轴和y轴
const xAxis = d3.axisBottom(xScale).ticks(d3.timeMinute.every(10));
const yAxis = d3.axisLeft(yScale);
// 添加x轴和y轴到SVG
svg.append("g")
.attr("class", "x-axis")
.attr("transform", `translate(0,${height})`)
.call(xAxis);
svg.append("g")
.attr("class", "y-axis")
.call(yAxis);
// 绘制温度和湿度曲线
svg.append("path")
.data([data.filter((d) => d.dtype === "temperature")])
.attr("class", "temperature-line")
.attr("d", temperatureLine);
svg.append("path")
.data([data.filter((d) => d.dtype === "humidity")])
.attr("class", "humidity-line")
.attr("d", humidityLine);
}).catch((error) => {
console.error("Error loading or parsing CSV:", error);
});
默认情况下,
path
已填充且没有描边。对于折线图,您可能想要相反的情况。因此,你需要类似的东西
svg.append("path")
.data([data.filter((d) => d.dtype === "temperature")])
.attr("class", "temperature-line")
.attr("d", temperatureLine)
.attr('fill', 'none')
.attr('stroke', 'black')
.attr('stroke-width', 3)
这是一个示例,其中初始路径缺少最后三行,但您可以使用按钮更新您所看到的内容:
let div = d3.select('div#viz')
let w = 500;
let h = 300;
let deg = Math.PI/180;
let pts = d3.range(0,w).map(x => [x,50*Math.sin(x*deg) + 150]);
let svg = div.append('svg')
.attr('viewBox', [0,0,w,h])
svg.append('path')
.attr('d', d3.line()(pts))
d3.select('button').on('click', update)
function update() {
svg.select('path')
.attr('fill', 'none')
.attr('stroke', 'black')
.attr('stroke-width', 3)
}
<script src="https://d3js.org/d3.v6.min.js"></script>
<div id="viz"></div>
<button>Update</button>