在窗口调整大小时调整d3生成的SVG大小会错误地移动我的图表数据

时间:2016-09-28 23:13:40

标签: javascript d3.js svg

我有5个div元素包含5个svgs。他们的id是数字和程序生成的:

<div id="svg-container-total"></div>
<div id="svg-container-3"></div>
<div id="svg-container-6"></div>
<div id="svg-container-12"></div>
<div id="svg-container-24"></div>

我创建了一些变量并使用techan.js来定义比例,范围等。请注意,使用#svg-container-total来定义宽度是可以的,因为所有的svg都将是同样创造

//defining misc variables
var margin = {top: 20, right: 60, bottom: 80, left: 60},
    width = parseInt(d3.select('#svg-container-total').style('width'),10) - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

//Defining chart scale
var x = techan.scale.financetime()
    .range([0, width]);

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

//initializing chart data function
var close = techan.plot.close()
    .xScale(x)
    .yScale(y);

然后我进入一个循环来创建所有的SVG。我的数据只是一些价格数据:

// INSERT SVG (IN THE LOOP NOW)
var svg = d3.select("#svg-container-"+frequency).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 + ")");

var accessor = close.accessor();

x.domain(data.map(accessor.d));
y.domain(techan.scale.plot.ohlc(data,accessor).domain());

svg.append("g")
   .datum(data)
   .attr("class", "performance_"+frequency)
   .call(close);

到目前为止一切顺利。结果如下。现在有5个图表,如下面的5个单独行中的图表。 enter image description here

我现在定义了一个resize函数并监听window resize(请注意,frequency数组允许我循环遍历不同的svg容器):

function resize() {
    //Find new window dimensions
    width = parseInt(d3.select('#svg-container-total').style('width'), 10);
    width = width - margin.left - margin.right;

    //Update range of scale with new width
    x.range([0, width]);

    for (var i = 0; i<frequencies.length; i++) {
        //Update chart contents
        d3.select("#svg-container-"+frequencies[i]+" svg")
          .attr("width", width + margin.left + margin.right)
          .attr("height", height + margin.top + margin.bottom);

        d3.selectAll(".performance_"+frequencies[i])
          .call(close);
    }
}

但是我的结果现在看起来像这样: enter image description here

除了实际数据点之外,所有内容似乎都正确调整大小。似乎数据点总是垂直移动一些量。每个图表似乎垂直移动了不同的数量,尽管每次我点击刷新并再次调整窗口大小时它们的移动都是一致的。

我认为这个问题与几个SVG访问同一个变量有关:

var close = techan.plot.close()

但我不知道为什么会垂直移动数据。此外,由于所有图表的高度和宽度都相同,我不认为访问&#34;关闭&#34;在循环中多次出现问题。

我这样想,因为当我只渲染一个图时,这个问题不会发生。

有什么想法吗?

参考:http://bl.ocks.org/andredumas/af8674d57980790137a0

1 个答案:

答案 0 :(得分:0)

1.after:

var svg = d3.select("#svg-container-"+frequency).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 + ")");

插入:

var defs = svg.append("defs"); 
    defs.append("clipPath").attr('id','clip-path'+frequency)
    .append('rect').attr('width',width + margin.left + margin.right)
    .attr('height',height + margin.top + margin.bottom);

2.查找代码并插入:

.attr('clip-path','url(#clip-path'+frequency')')

示例(在我的代码中):

var svg = d3.select("body").append("svg")
    .attr("width", width) 
    .attr("height", height)
    .attr("viewBox", "0 0 "+width+" "+ height)
    .attr("preserveAspectRatio", "xMinYMax none")
    .attr("xml:space","preserve")
    .attr("shape-rendering","optimizeSpeed") 
    .attr("id", "chart1")
    .append("g")
    .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
    .attr("id", "layers")
    .on("click", dvevent) 
    .call(d3.zoom()
        .duration(-1)
        .extent([[0, 0], [width, height]])
        .translateExtent([[0, 0], [width, height]])
        .scaleExtent([1, 20])
        .on("zoom", zoomed));

  var defs = svg.append("defs"); defs.append("clipPath").attr('id','clip-path').append('rect').attr('width',width).attr('height',height);

 var layer = svg.selectAll(".layer")
    .data(layers)
  .enter().append("g")
    .attr("class", "layer")
    .attr('clip-path','url(#clip-path)')

...skipped...

 var rect = layer.selectAll("rect")
    .data(function(d) {return d.filter(function(d,i) { ...skipped... })})
    .enter().append("rect")

...skipped...