D3.js 缩放和平移中的线条svg数据映射问题

linesvg data mapping issue in D3.js zoom and pan

提问人:Lakshmi 提问时间:10/31/2023 更新时间:10/31/2023 访问量:41

问:

我已经在图表上实现了缩放和平移功能,但我遇到了一个问题。缩放和平移时,x 和 y 刻度会正确调整,线条会按预期展开和收缩。但是,数据似乎正在映射到“行”。换言之,新的刻度值未应用于线条,从而导致不一致。当我将鼠标悬停在线上时,工具提示会显示一些数据,但是当我将鼠标悬停在线条之外时,问题就出现了,并且工具提示仍然显示数据。通过调试,我意识到数据没有正确映射到行。我对 d3.js 比较陌生,感谢您在解决问题方面的帮助。

在下面提供的示例代码中,缩放和平移功能似乎无法按预期工作。我分享这段代码是为了说明我使用的属性。但是,在我的实际项目中,缩放和平移可以正常工作。

预期结果我希望数据能够正确映射到具有新刻度值的线条,并且将鼠标悬停在线外不应显示工具提示数据。

实际结果数据未正确映射到具有新刻度值的线条,并且将鼠标悬停在线外会显示工具提示数据

const svgWidth = 488;
const svgHeight = 300;
const margin = {
    top: 18,
    left: 60,
    right: 35,
    bottom: 25,
};
const width = svgWidth - margin.left - margin.right;
const height = svgHeight - margin.bottom - margin.top;

const svg = d3.select("body").append("svg")
    .attr("width", svgWidth)
    .attr("height", svgHeight)
    .append("g")
    .attr("transform", \`translate(${margin.left}, ${margin.top})\`);

const xScale = d3.scaleLinear()
    .domain(\[0, 200\])
    .range(\[0, width\]);

const yScale = d3.scaleLinear()
    .domain(\[0, 100\])
    .range(\[height, 0\]);

const xAxis = d3.axisBottom(xScale).ticks(10).tickSize(-height);
const yAxis = d3.axisLeft(yScale).ticks(5).tickSize(-width);

const zoomAndPan = d3.zoom()
    .scaleExtent(\[0.2, 5\])
    .translateExtent(\[\[-7808, -7090\], \[7000, 7800\])
    .on("zoom", (e) =\> {
        svg.selectAll("g.line").attr("transform", e.transform);
        svg.select(".x.axis").call(xAxis.scale(e.transform.rescaleX(xScale)));
        svg.select(".y.axis").call(yAxis.scale(e.transform.rescaleY(yScale)));
    });

svg.call(zoomAndPan);

svg.append("g")
    .attr("class", "x axis")
    .attr("transform", \`translate(0, ${height})\`)
    .call(xAxis);

svg.append("g")
    .attr("class", "y axis")
    .call(yAxis);

const lineSVG = d3.line()
    .x((d) =\> xScale(d.x))
    .y((d) =\> yScale(d.y));

const data = \[
    { 'x': 1, 'y': 6 },
    { 'x': 2, 'y': 5 },
    { 'x': 3, 'y': 18 },
    // Add more data points here
\];

const lines = svg.append("g").attr("class", "lines");

lines.selectAll(".line-group")
    .data(\[data\])
    .enter()
    .append("g")
    .attr("class", "line-group")
    .append("path")
    .attr("class", "line")
    .attr("d", (d) =\> lineSVG(d))
    .style("stroke", "red")
    .style("opacity", 1.0);
 
D3.js 图表 折线 缩放 平移

评论

0赞 Mark 11/1/2023
在这一行中,你没有类为“line”的元素。你的意思是“线”还是“线组”?svg.selectAll('g.line').attr('transform', e.transform);g
0赞 Lakshmi 11/2/2023
@Mark 对于代码编辑过程中的格式问题,我深表歉意。似乎不知何故,标签从那一行中删除了。代码是 .我使用的是多线图,其中“线”包含“线组”。那么,选择“线”或“线组”应该是一样的,对吧?如果我弄错了,请纠正我。svgsvg.selectAll("svg g .line-group").attr("transform",e.transform)
0赞 Lakshmi 11/2/2023
@Mark 仅供参考:这是显示工具提示行的代码:。在此代码中,我们附加了一行,值得注意的是,“lines”包含“line-group”和“line”类。我不确定这是否会导致任何问题。请查看此内容并协助我解决问题。先谢谢你。const tooltipLine=svg.append("line").attr("class","tooltip-line");

答: 暂无答案