javascript - 对数据绑定(bind)和选择特定数据感到困惑

标签 javascript d3.js

我是 d3 的新手,对将数据连接到 DOM 元素的概念感到困惑。我在 JSON 中有一个非常重要的数据存储,我很难分离出不同的部分。 这是我的 JSON:

var data ={ 
    "groups" :
    [{
        "name": "group1",
        "atts":
        [{
            "nodes": 
             [
             {"id": "root", "name": "Plaintext Router" },
             { "id": "B", "name": "Ethernet Switch" },
             { "id": "C", "name": "1.10" },
             { "id": "D", "name": "1.1" },
             { "id": "E", "name": "1.2" }
             ], 
            "links": 
             [{ "source": "root", "target": "B" },
              { "source": "root", "target": "C" },
              { "source": "root", "target": "D" },
              { "source": "root", "target": "E" },
             ]
        }]
    },
    {
        "name": "group2",
        "atts":
        [{
            "nodes":
             [
             { "id": "root", "name": "Plaintext Router" },
             { "id": "B", "name": "Ethernet Switch" },
             { "id": "C", "name": "1.1" },
             { "id": "D", "name": "1.2" }
             ],
            "links":
             [{ "source": "root", "target": "B" },
              { "source": "root", "target": "C" },
              { "source": "root", "target": "D" },
             ]

        }]
    }
]
}

因此,我想为两个组创建网络 map 。根节点是一个中心,链接以辐条模式发散到中心周围的其他节点。

我希望能够选择要可视化的组。我不希望它们同时可视化。

我必须尝试执行的代码如下。

var height = 600;
var width = 600;

var svg = d3.select("body").append("svg")
  .attr("width",width)
  .attr("height",height);

var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) { return d.id; }).distance(300))
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(width / 2, height / 2));

var link = svg.append("g")
  .selectAll("line")
  .data(data.groups, key)

[[需要获取所选组的链接数组]]

  .enter()
  .append("line")
  .attr("stroke","green");

var groups = svg.selectAll(".node")
    .data(data.groups, key)

[[需要获取所选组的节点数组]]

    .enter()
    .append("g");

var node = groups.append("rect")
    .attr("width", function(d) { return d.w * 2; })
    .attr("height", function(d) { return d.h * 2; })
    .style("fill", function(d) { return "url(#" + d.icon + ")"; });

function key(d) {
    return ((d.groups.name === "group1") ? d.groups.atts : null);
}

上面的关键函数表示我要映射'group1'组。我遇到的问题是我不知道如何获得与所选组相关联的“节点”和“链接”的“atts”数组。我希望能够在需要的地方分配节点和链接。

我现在得到的错误是: “无法获取未定义或空引用的属性‘名称’” 在“关键”功能中。

我省略了其他指令,例如 svg:patterns 和其他指令,以尽量让事情变得简单。我希望这个例子能传达我的观点。

我很感激你能为此提供的任何帮助。

最佳答案

使用 .filter((d) => {...},您可以过滤数据并设定应设置数据的条件。我希望这就是您的意思...

过滤器示例:

const words = ["spray", "limit", "elite", "exuberant", "destruction", "present", "happy"];
let longWords = words.filter(word => word.length > 6)

JS

var data ={ 
    "groups" :
    [{
        "name": "group1",
        "atts":
        [{
            "nodes": 
             [
             {"id": "root", "name": "Plaintext Router" },
             { "id": "B", "name": "Ethernet Switch" },
             { "id": "C", "name": "1.10" },
             { "id": "D", "name": "1.1" },
             { "id": "E", "name": "1.2" }
             ], 
            "links": 
             [{ "source": "root", "target": "B" },
              { "source": "root", "target": "C" },
              { "source": "root", "target": "D" },
              { "source": "root", "target": "E" },
             ]
        }]
    },
    {
        "name": "group2",
        "atts":
        [{
            "nodes":
             [
             { "id": "root", "name": "Plaintext Router" },
             { "id": "B", "name": "Ethernet Switch" },
             { "id": "C", "name": "1.1" },
             { "id": "D", "name": "1.2" }
             ],
            "links":
             [{ "source": "root", "target": "B" },
              { "source": "root", "target": "C" },
              { "source": "root", "target": "D" },
             ]

        }]
    }
]
}





var height = 600;
var width = 600;

var svg = d3.select("body").append("svg")
  .attr("width",width)
  .attr("height",height);

var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) { return d.id; }).distance(300))
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(width / 2, height / 2));

var link = svg.append("g")
  .selectAll("line")
  .data(data.groups.filter((d)=>{
    console.log("link")
    console.log(d)
    }))
  .enter()
  .append("line")
  .attr("stroke","green");

var groups = svg.selectAll(".node")
    .data(data.groups.filter((d)=>{
    console.log("group")
    console.log(d)
    }))
    .enter()
    .append("g");

var node = groups.append("rect")
    .attr("width", function(d) { return d.w * 2; })
    .attr("height", function(d) { return d.h * 2; })
    .style("fill", function(d) { return "url(#" + d.icon + ")"; });

function key(d) {
    return ((d.name === "group1") ? d.atts : null);
}

JS Fiddle

关于javascript - 对数据绑定(bind)和选择特定数据感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49416243/

相关文章:

javascript - <img/> 缩放到最接近的纵横比

javascript - 未捕获的类型错误 : Cannot read property 'setState' of undefined

javascript - d3.js 为每个数据点创建两个元素

javascript - D3 X轴上加间隔

javascript - d3 画笔和 clipPath : Main chart outside bounds

javascript - 在单页网站上替换 Div 的内容

JavaScript 事件处理程序范围

svg - 在D3强制有向图中的链接上添加文本/标签

css - D3js 包含不止一种样式

javascript - iframe加载后隐藏链接