代码之家  ›  专栏  ›  技术社区  ›  A Zibuda

基于颜色选择器的强制布局节点颜色修改

  •  0
  • A Zibuda  · 技术社区  · 6 年前

    我正在尝试使用颜色选择器修改强制布局中某些节点的颜色。

    我没有找到任何例子来说明如何在部队布局中修改元素,而不需要在这些元素内/由这些元素触发事件。

    This example 正在用按钮更新布局,但只更改传递的数据,然后更新图表。我使用的数据包含一个“组”,它决定JS中定义的颜色。因此,更新数据不是一个选项,但是更新变量也不起作用。

    This question 询问有关更新模拟本身的力/属性而不是其元素的问题,此处的解决方案对我不起作用,因为重新加热模拟不会拾取更改的颜色。

    var cp = document.getElementById("useCasePicker");
    cp.value = useCaseColor;
    cp.addEventListener("change", updateColor, false);    
    
    function updateColor(event)
    {
        useCaseColor = event.target.value;
        update();
    }
    

    这是我试图做的(使用update()函数用任何新的输入重新绘制图形),但是我想更改的已经存在的节点会被跳过,因为它们已经存在。

    我也试过这样做(节点是 <g> 包含所有圆的元素-

    node.selectAll("circle").style("fill", useCaseColor);
    

    这也不适用于改变颜色-

    node.selectAll("circle").remove();
    label.selectAll("text").remove();
    update();
    

    我想我可以做一件像 newColor 事件设置的标志,如果为真,则以某种方式从节点本身触发事件,但我认为有更好的方法可以做到这一点。

    这是如何在 update() 功能。

    node = node.data(config.nodes, d => d.id);
        node.exit().remove();
        node = node.enter().append("circle")
                .attr("class", "node")
                .attr("r", function (d) {
                    switch(d.group)
                    {
                        case "use case":
                            return useCaseRad;
                        case "data service":
                            return dataServRad;
                        case "source":
                            return sourceRad;
                    }
                })
                .attr("fill", function (d) {
                    switch(d.group)
                    {
                        case "use case":
                            return useCaseColor;
                        case "data service":
                            return dataServColor;
                        case "source":
                            return sourceColor;
                    }
                })
                .attr("stroke", "black")
                .call(d3.drag()
                .on("start", dragstarted)
                .on("drag", dragged)
                .on("end", dragended))
                .on("mouseover", mouseOver)
                .on("mouseout", mouseOut)
                .merge(node);
    

    如果需要的话,我可以提供更多的代码,但是我知道图表的所有功能都很好,我只想能够更新颜色,而不必破坏整个图表并重新绘制它。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Danylo Rosiichuk    6 年前

    您不必破坏图形-只需在合并后放置Fill方法调用。

    .merge(data)
    .attr("fill", function (d) {
          switch(d.group) {
             case "use case":
                 return useCaseColor;
             case "data service":
                 return dataServColor;
             case "source":
                 return sourceColor;
          }
    })
    

    合并允许您同时处理初始和输入选择,以便正确更新。