【问题标题】:d3 update paths and circles in Graphd3 更新 Graph 中的路径和圆圈
【发布时间】:2018-04-13 15:27:40
【问题描述】:

我想更新图表,但它不起作用。我想更新线条和圆圈。我尝试添加

.exit().remove()

更新圈子和

  g.selectAll("path").attr("d", line);

更新路径。

但是它不起作用。

使用 exit().remove() 更新外部组可以正常工作。 (本例中的复选框)。

仅更新路径和圆圈不起作用。 (本例中为更新按钮)

我不想删除图表中的所有线条并再次附加它,因为我想在数据更改时添加过渡。

这是一个 JS Fiddle:LINK 这是我的代码:

var data = [
  [{
    point: {
      x: 10,
      y: 10
    }
  }, {
    point: {
      x: 100,
      y: 30
    }
  }],
  [{
      point: {
        x: 30,
        y: 100
      }
    }, {
      point: {
        x: 230,
        y: 30
      }
    },
    {
      point: {
        x: 50,
        y: 200
      }
    },
    {
      point: {
        x: 50,
        y: 300
      }
    },
  ]
];

var svg = d3.select("svg");

var line = d3.line()
  .x((d) => d.point.x)
  .y((d) => d.point.y);

function updateGraph() {
  console.log(data)
  var allGroup = svg.selectAll(".pathGroup").data(data);
  var g = allGroup.enter()
    .append("g")
    .attr("class", "pathGroup")
  allGroup.exit().remove()

  g.append("path")
    .attr("class", "line")
    .attr("stroke", "red")
    .attr("stroke-width", "1px")
    .attr("d", line);

  g.selectAll("path").attr("d", line);

  g.selectAll(null)
    .data(d => d)
    .enter()
    .append("circle")
    .attr("r", 4)
    .attr("fill", "teal")
    .attr("cx", d => d.point.x)
    .attr("cy", d => d.point.y)
    .exit().remove()

}
updateGraph()

document.getElementById('update').onclick = function(e) {

  data = [
    [{
      point: {
        x: 10,
        y: 10
      }
    }, {
      point: {
        x: 100,
        y: 30
      }
    }],
    [{
        point: {
          x: 30,
          y: 100
        }
      }, {
        point: {
          x: 230,
          y: 30
        }
      },
      {
        point: {
          x: 50,
          y: 300
        }
      },
    ]
  ];
  updateGraph()
}


$('#cb1').click(function() {
  if ($(this).is(':checked')) {
    data = [
      [{
        point: {
          x: 10,
          y: 10
        }
      }, {
        point: {
          x: 100,
          y: 30
        }
      }],
      [{
          point: {
            x: 30,
            y: 100
          }
        }, {
          point: {
            x: 230,
            y: 30
          }
        },
        {
          point: {
            x: 50,
            y: 200
          }
        },
        {
          point: {
            x: 50,
            y: 300
          }
        },
      ]
    ];

  } else {
    data = [
      [{
        point: {
          x: 10,
          y: 10
        }
      }, {
        point: {
          x: 100,
          y: 30
        }
      }]
    ];
  }
  updateGraph()
});

【问题讨论】:

    标签: javascript d3.js graph


    【解决方案1】:

    问题

    allGroup.exit().remove() 什么都不做的原因是更新后的数据集仍然具有与原始数据集相同的项目数。因此退出选择为空。

    变量data 包含线,而不是点。在页面加载时定义的一个,update 监听器内部的一个包含两行,只是它们的点数不同。

    您可以通过在函数updateGraph 中添加console.log(data.length) 来检查这一点。

    解决方案 1

    改变你的数据结构。您可以为每一行分配一个id 属性,并使用.datakey 函数。参看。 d3-selection documentation.

    更新了 jsFiddle 实现方案一:see here

    此解决方案需要较少的更改。

    解决方案 2

    如果您无法控制数据结构,您可以在update 选项内转换线条图,而不是exit 选项。

    【讨论】:

    • id 不明白为什么我必须使用 p3 作为 id?当我想更新。所以每次我更新我都需要一个新的ID?
    • 如果我返回未定义,为什么它会起作用。就像在这个 js Fiddle jsfiddle.net/3uebkmz5/129
    • 是的,id 必须不同,以便删除的行进入exit 选择。如果使用相同的 Id,则该行将进入 update 选择。参看。文档链接和在线教程
    • 之所以有效,是因为 d3-selection 的逻辑出于某种原因让这种情况发生。定义实际的不同键更安全。您可以根据项目在数组中的位置生成它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-01
    • 2018-03-25
    • 1970-01-01
    • 2016-08-28
    相关资源
    最近更新 更多