You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

r2d3调用d3.js v3绘制柱状图窗口调整大小时消失问题求助

问题成因

  • r2d3默认开启窗口resize响应逻辑,窗口尺寸变化时会自动清空原有容器内容,重新执行整个JS脚本。你当前的代码中将svg初始化、宽高计算、比例尺定义逻辑全部放在了r2d3.onRender回调外部,仅会在页面首次加载时执行一次。resize触发时代码引用的还是已经被清理的旧svg节点、首次加载的旧尺寸值,就会触发「Node cannot be found in the current page」报错。
  • r2d3.onRender仅会在首次渲染完成后执行一次,resize清空容器后不会重新触发内部的绘图逻辑,自然没有新的图表生成,只会留下空容器或者系统自动生成的错误提示节点。

解决方法

有两种可选方案,按需选择即可:

方案1:保留resize响应能力,修改JS代码

将所有绘图逻辑移入r2d3.onRender回调内,每次渲染都使用回调传入的最新宽高参数,同时每次渲染前先清空容器内的旧内容,修改后的test.js代码如下:

// !preview r2d3 data=readr::read_tsv("X:/D3 Practice/data.tsv"), d3_version = "3", container="div"

function type(d) {
  d.frequency = +d.frequency;
  return d;
}

r2d3.onRender(function(data, div, w, h, options) {
  // 清空容器内旧内容
  div.selectAll("*").remove();
  
  // 用最新的容器尺寸计算绘图区域
  var margin = {top: 40, right: 20, bottom: 30, left: 40},
      width = w - margin.left - margin.right,
      height = h - margin.top - margin.bottom;

  var formatPercent = d3.format(".0%");

  var x = d3.scale.ordinal()
      .rangeRoundBands([0, width], .1);

  var y = d3.scale.linear()
      .range([height, 0]);

  var xAxis = d3.svg.axis()
      .scale(x)
      .orient("bottom");

  var yAxis = d3.svg.axis()
      .scale(y)
      .orient("left")
      .tickFormat(formatPercent);

  // 重新创建svg节点
  var svg = div.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 + ")");

  x.domain(data.map(function(d) { return d.letter; }));
  y.domain([0, d3.max(data, function(d) { return d.frequency; })]);

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Frequency");

  svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.letter); })
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.frequency); })
      .attr("height", function(d) { return height - y(d.frequency); })
});

方案2:关闭resize响应

如果不需要图表跟随窗口尺寸变化,可以直接在R调用代码中添加resize = FALSE参数,关闭resize重绘逻辑即可:

library(r2d3)
r2d3(data = readr::read_tsv("X:/D3 Practice/data.tsv"),
     script = "X:/D3 Practice/test.js",
     d3_version = "3",
     container="div",
     resize = FALSE)

内容的提问来源于stack exchange,提问作者DiamondJoe12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 08:54:10