网格线正在重新创建并相互叠加

时间:2017-10-01 12:35:09

标签: javascript d3.js

我正在玩一些d3代码 - 要创建y轴,我会执行以下操作:

function renderYAxis(svg) { 

 var yAxis = d3.svg.axis()
     .orient("left")
     .scale(_y.range([quadrantHeight(), 0]))
     .tickFormat(d3.format("s"));

 axisData = _currentData.filter(function(row) {
     if ((row['filter1'] === _filter1)) {
         return true;
     }
 }).filter(function(row) {
     if ((row['filter2'] === _filter2)) {
         return true;
     }
 }).map(function(d) {
     return {
         y: +d["Y"]
     };
 });
 var minY2 = d3.min(axisData, function(d) { return d.y });
 if (minY2 > 0) {
     minY2 = 0;
 };
 _y.domain([minY2, d3.max(axisData, function(d) { return d.y })])


 if (!_axesYG) {
     _axesYG = svg
         .append("g")
         .attr("class", "y axis"); 
 }

 _axesYG
     .attr("transform", function() {
         return "translate(" + xStart() + "," + yEnd() + ")";
     })
     .transition()
     .duration(1000)
     .call(yAxis);

  //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> maybe following needs changing somehow? >>>>>>>>>>>>>>
  d3.selectAll("g.y g.tick")
     .append("line")
     .classed("grid-line", true)
     .attr("x1", 0)
     .attr("y1", 0)
     .attr("x2", quadrantWidth())
     .attr("y2", 0);

}

图表有一个转换,但在转换几次之后,一些网格线正在复制并相互叠加 - 因此产生一些较粗的线条。我已经在上面标出了我认为可能存在的问题,我不确定如何更改此代码 - 是否有标准方法?

此行为的完整工作示例保存在此处:docs

如果多次按下该按钮,您将看到正在重新创建和覆盖的转换之前和之后共享的公共网格线。这两个:

http://plnkr.co/edit/JD52TfAddZSpNR3oaMRv?p=preview

任何帮助都非常感激。

3 个答案:

答案 0 :(得分:2)

一个简单的解决方案就是将刻度线宽度设置为负值:

.innerTickSize(-quadrantWidth());

这样,您不必担心追加,删除或更新线条,也不会有重复的元素:轴生成器会为您完成所有这些操作。

以下是更新的plunker:http://plnkr.co/edit/BoP4hEkILlwJzRuCJFBD?p=preview

编辑:您在your answer中提到您在使用Nick Zhu的方法时遇到问题。那是因为你的选择不正确。它应该是这样的:

var lines = d3.selectAll("g.y g.tick")

lines.selectAll(".grid-line")
    .remove();

lines.append("line")
    .classed("grid-line", true)
    .attr("x1", 0)
    .attr("y1", 0)
    .attr("x2", quadrantWidth())
    .attr("y2", 0);

以下是相应的plunker:http://plnkr.co/edit/189hJBepdVVreLghBgc0?p=preview

答案 1 :(得分:1)

这是一个简单的修复(hack),因为原始代码结构很难更改为正确遵循常规更新模式:

      // remove old ones
      d3.selectAll(".grid-line.y-axis")
         .remove();

      // draw new ones
      // add a new class y-axis to avoid deleting the x axis above
      d3.selectAll("g.y g.tick")
         .append("line")
         .classed("grid-line y-axis", true)
         .attr("x1", 0)
         .attr("y1", 0)
         .attr("x2", quadrantWidth())
         .attr("y2", 0);

http://plnkr.co/edit/wdQmllRrrILtXsarXqLY?p=preview

更正确的方法是遵循常规更新模式:https://bl.ocks.org/mbostock/3808234

答案 2 :(得分:1)

为了完整起见,我想我会添加以下内容,这是我在Nick Qi Zhu的书中找到的。我认为它遵循一般更新模式以及网格线。虽然即使加上这个,我仍然可以复制网格线!

function renderYGridlines() {
     var lines = d3.selectAll("g.y g.tick")
       .select("grid-line y-axis")
       .remove();

     lines = d3.selectAll("g.y g.tick")
       .append("line")
       .classed("grid-line", true)

     lines.attr("x1", 0)
       .attr("y1", 0)
       .attr("x2", quadrantWidth())
       .attr("y2", 0);
   }