Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript D3-刷新图表时重置缩放?_Javascript_Svg_D3.js - Fatal编程技术网

Javascript D3-刷新图表时重置缩放?

Javascript D3-刷新图表时重置缩放?,javascript,svg,d3.js,Javascript,Svg,D3.js,我正在做D3时间尺度/价格尺度的财务图表。图表SVG本身使用zoom()以几何方式平移和缩放数据,并重新绘制轴。图表下方是一个SVG画笔窗格,它以较高的级别显示整个数据集,并允许平移本身。我面临的问题与此小提琴中显示的行为相同(不是我的代码):。刷牙后缩放会导致跳跃行为,因为zoom()从未从刷牙()中拾取更改 Zoom和brush独立工作,但我很难让它们一起工作。当图表被刷的时候,我希望zoom能够检测到这一点,所以下一次图表被缩放时,它会在刷掉的地方重新开始。反之亦然 我已经设法设置了一个同

我正在做D3时间尺度/价格尺度的财务图表。图表SVG本身使用zoom()以几何方式平移和缩放数据,并重新绘制轴。图表下方是一个SVG画笔窗格,它以较高的级别显示整个数据集,并允许平移本身。我面临的问题与此小提琴中显示的行为相同(不是我的代码):。刷牙后缩放会导致跳跃行为,因为zoom()从未从刷牙()中拾取更改

Zoom和brush独立工作,但我很难让它们一起工作。当图表被刷的时候,我希望zoom能够检测到这一点,所以下一次图表被缩放时,它会在刷掉的地方重新开始。反之亦然

我已经设法设置了一个同步功能,以便在启动缩放时使画笔正确更新,但我无法使相反的功能正常工作-在导航器中出现画笔时更新图表缩放。我找了好几个小时都没找到。有没有补丁可以修复这个问题?很抱歉代码块太长,但我希望设置上下文会有所帮助

设置代码(为了简洁起见,省略了一些基本变量):

笔刷和缩放功能:

// zoom - brush synchronizations
function updateBrushFromZoom() {
  if ((dateScale.domain()[0] <= minX) && (dateScale.domain()[1] >= maxX)) {
    viewport.clear();
  } else {
    viewport.extent(dateScale.domain());
  }
  navChart.select('.viewport').call(viewport);
}

function updateZoomFromBrush() {
  // help!!
}

function brush() {
  var g = d3.selectAll('svg').select('g');
  var newDomain = viewport.extent();
  if (newDomain[0].getTime() !== newDomain[1].getTime()) {
    dateScale.domain([newDomain[0], newDomain[1]]);
    var xTransform = fc.utilities.xScaleTransform(initialXScale, dateScale);

    // define new data set
    var range = moment().range(newDomain[0], newDomain[1]);
    var rangeData = [];
    for (var i = 0; i < data.length; i += 1) {
      if (range.contains(new Date(data[i].startTime*1000))) {
        rangeData.push(data[i]);
      }
    }
    // define new mins and maxes
    var newMinY = d3.min(rangeData, function (d) {
      return d.low;
    });
    var newMaxY = d3.max(rangeData, function (d) {
      return d.high;
    });

    // set new yScale
    priceScale.domain([newMinY, newMaxY]);
    var yTransform = fc.utilities.yScaleTransform(initialYScale, priceScale);

    // draw new axes on main chart
    g.select('.fcChartArea .date.axis')
      .call(dateAxis);
    g.select('.fcChartArea .price.axis')
      .call(priceAxis);

    // transform the data to fit new chart viewport
    g.select('.series')
      .attr('transform', 'translate(' + xTransform.translate + ',' + yTransform.translate+ ')' + ' scale(' + xTransform.scale + ',' + yTransform.scale + ')');
  }
  else {
    // remove transformation
    g.select('.series')
      .attr('transform', null);
  }
  updateZoomFromBrush();
}

// Zoom functions
function zoom() {
  var g = d3.selectAll('svg').select('g');
  // set new xScale
  var newDomain = dateScale.domain();
  var xTransformTranslate = d3.event.translate[0];
  var xTransformScale = d3.event.scale;

  // define new data set
  var range = moment().range(newDomain[0], newDomain[1]);
  var rangeData = [];
  for (var i = 0; i < data.length; i += 1) {
    if (range.contains(new Date(data[i].startTime*1000))) {
      rangeData.push(data[i]);
    }
  }

  // define new max and min
  var newMinY = d3.min(rangeData, function (d) {
    return d.low;
  });
  var newMaxY = d3.max(rangeData, function (d) {
    return d.high;
  });

  // set new yScale
  priceScale.domain([newMinY, newMaxY]);
  var yTransform = fc.utilities.yScaleTransform(initialYScale, priceScale);

  // draw new axes on main chart
  g.select('.fcChartArea .date.axis')
    .call(dateAxis);
  g.select('.fcChartArea .price.axis')
    .call(priceAxis);

  // transform the data to fit new chart viewport
  g.select('.series')
    .attr('transform', 'translate(' + xTransformTranslate + ',' + yTransform.translate+ ')' + ' scale(' + xTransformScale + ',' + yTransform.scale + ')');

  // update SVG navigator
  updateBrushFromZoom();
}
fc.utilities.yScaleTransform = function(oldScale, newScale) {
  var oldDomain = oldScale.domain();
  var newDomain = newScale.domain();
  var scale = (oldDomain[1] - oldDomain[0]) / (newDomain[1] - newDomain[0]);
  var translate = scale * (oldScale.range()[1] - oldScale(newDomain[1]));
  return {
    translate: translate,
    scale: scale
  };
};

fc.utilities.xScaleTransform = function(oldScale, newScale) {
  var oldDomain = oldScale.domain();
  var newDomain = newScale.domain();
  var scale = (oldDomain[1] - oldDomain[0]) / (newDomain[1] - newDomain[0]);
  var translate = scale * (oldScale.range()[0] - oldScale(newDomain[0]));
  return {
    translate: translate,
    scale: scale
  };
};

updateZoomFromBrush()
中,使用
zoom.x(dateScale)
将比例重新绑定到缩放行为

这是必需的,因为
d3.behavior.zoom()
对传入的标尺的副本进行操作,因此,如果不重新绑定标尺,该行为将不会在
brush()
中对标尺的域进行任何更改


请参见
updateZoomFromBrush()
中的此示例,使用
zoom.x(dateScale)
将缩放比例重新绑定到缩放行为

这是必需的,因为
d3.behavior.zoom()
对传入的标尺的副本进行操作,因此,如果不重新绑定标尺,该行为将不会在
brush()
中对标尺的域进行任何更改


请参见
updateZoomFromBrush()
中的此示例,使用
zoom.x(dateScale)
将缩放比例重新绑定到缩放行为

这是必需的,因为
d3.behavior.zoom()
对传入的标尺的副本进行操作,因此,如果不重新绑定标尺,该行为将不会在
brush()
中对标尺的域进行任何更改


请参见
updateZoomFromBrush()
中的此示例,使用
zoom.x(dateScale)
将缩放比例重新绑定到缩放行为

这是必需的,因为
d3.behavior.zoom()
对传入的标尺的副本进行操作,因此,如果不重新绑定标尺,该行为将不会在
brush()
中对标尺的域进行任何更改


看到这个例子可能会有所帮助。我看到了这个问题,但发布的解决方案本身也有问题。可能会有帮助。我看到了这个问题,但发布的解决方案本身也有问题。可能会有帮助。我看到了这个问题,但发布的解决方案本身也有问题。可能会有帮助。我看到了这个问题,但发布的解决方案本身也有问题。
fc.utilities.yScaleTransform = function(oldScale, newScale) {
  var oldDomain = oldScale.domain();
  var newDomain = newScale.domain();
  var scale = (oldDomain[1] - oldDomain[0]) / (newDomain[1] - newDomain[0]);
  var translate = scale * (oldScale.range()[1] - oldScale(newDomain[1]));
  return {
    translate: translate,
    scale: scale
  };
};

fc.utilities.xScaleTransform = function(oldScale, newScale) {
  var oldDomain = oldScale.domain();
  var newDomain = newScale.domain();
  var scale = (oldDomain[1] - oldDomain[0]) / (newDomain[1] - newDomain[0]);
  var translate = scale * (oldScale.range()[0] - oldScale(newDomain[0]));
  return {
    translate: translate,
    scale: scale
  };
};