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
相关产品推荐
相关产品推荐

