d3.js D3仅当元素不存在时追加元素

tyg4sfes  于 2022-11-12  发布在  其他
关注(0)|答案(4)|浏览(218)

我有一个问题与D3,如果我追加一个元素第二次我会得到重复的元素在父节点。

node.enter().insert("svg:g")
      .attr("class", 'test')
      .attr("width", '63px')
      .attr("height", '68px')
      .call(force.drag);

  node.append("svg:circle")
      .attr("class", "bg-circle")
      .attr("r", "30px");

例如,我将得到:

<g class="test">
   <circle class="bg-circle" />
   <circle class="bg-circle" />
</g>

但我想:

<g class="test">
   <circle class="bg-circle" />
</g>

即使我再次调用函数设置节点时也是如此。

8wtpewkr

8wtpewkr1#

我有一个初始化或更新绘图的函数,为了防止重复的样板文件被制作 * 同时 * 允许转换到元素,我最终做了以下操作:

const grid = d3.select('.grid').node()
  ? d3.select('.grid')
  : g.append('g')
      .attr('class', 'grid');
xpcnnkqh

xpcnnkqh2#

我遇到了同样的问题,预览的答案并没有帮助我,所以我通过这样做来解决它:
在我的html. index中,我有两个按钮,它们调用不同的数据源来制作相同类型的图表,所以每次我单击其中一个按钮时,我都会得到重复的图表(函数1调用带有_des的div的数据,函数2调用_ic div的数据)

<div>
  <h3>Graficas</h3>
  <label>
    <input id="des" type="checkbox" class="radio"  name="fooby[1][]" checked onchange='load_des(this)'/>data 1 </label>
  <label>
    <input id="ic" type="checkbox" class="radio"  name="fooby[1][]" onchange='load_ic(this)'/>data 2</label>
</div>

<div class="container">
    <div id="donut_des"></div>
    <div id="bars_des" ></div>
    <div id="donut_ic"></div>
    <div id="bars_ic" ></div>
</div>

因此,我在main.js文件中为每个函数添加了以下内容:

function load_des(obj) {
  if($(obj).is(":checked")){

  document.getElementById('donut_ic').innerHTML = "";
  document.getElementById('bars_ic').innerHTML = "";

// do everything else normally 
}

function load_ic(obj) {
  if($(obj).is(":checked")){

  document.getElementById('donut_des').innerHTML = "";
  document.getElementById('bars_des').innerHTML = "";

// do everything else normally 
}

希望这对任何人都有用,因为我不能用其他方法解决这个问题。

kgqe7b3p

kgqe7b3p3#

这个问题问了9年前,但我一直在努力与同样的问题,并修复这样

创建函数以检查

const d3ExistRootControl = <GElement extends BaseType, Datum, PElement extends BaseType, PDatum>(
  selection: Selection<GElement, Datum, PElement, PDatum>,
  createSelection: () => Selection<GElement, Datum, PElement, PDatum>) => {

  if (selection.size()) return selection;
  return createSelection();

};

用法

const mouseG = d3ExistRootControl(
    svg.select(`g.${config.classes.mouseOverEffects}`),
    () => svg.append('g')
      .attr('class', config.classes.mouseOverEffects)
  );

使用数据和类型实现

const mousePerLine = d3ExistRootControl(
        mouseG.selectAll(`.${config.classes.mousePerLine}`) as any,
        () => mouseG.selectAll(`.${config.classes.mousePerLine}`)
          .data(sumstat)
          .enter()
          .append('g')
          .attr('class', config.classes.mousePerLine)
  );
pbossiut

pbossiut4#

我猜你想用d3来画一些UI。我用了类似这样的东西:

function appendOnce(selection, s) {
        var l = s.split("."); // l[0] tag, l[0] dot separated classes

        var g = selection.selectAll(s)
            .data([0])

        g.enter().append(l[0])
            .attr("class", l.slice(1).join(" "))

        return g;
    }

    // and then use
    var clild = appendOnce(parent, "text.y-caption")
        .attr(...)
        .style(...);

相关问题