Json 从d3中的局部变量读取节点数据

Json 从d3中的局部变量读取节点数据,json,d3.js,Json,D3.js,如何从局部变量jsonNodes(JSON数据)而不是从文件中读取数据来创建d3图形,我正在使用的示例 下面是我正在尝试的代码,按钮“Go”正在调用refresh函数,使用jsonNodes变量刷新图形。(实际上,我正在调用一个WebSocket服务来填充jsonNodes,但现在我只是在函数中硬编码了它) 当我点击“开始”按钮时,它什么也不做 <canvas width="960" height="500"></canvas> <body>

如何从局部变量
jsonNodes
(JSON数据)而不是从文件中读取数据来创建d3图形,我正在使用的示例

下面是我正在尝试的代码,按钮“Go”正在调用
refresh
函数,使用
jsonNodes
变量刷新图形。(实际上,我正在调用一个WebSocket服务来填充
jsonNodes
,但现在我只是在函数中硬编码了它)

当我点击“开始”按钮时,它什么也不做

  <canvas width="960" height="500"></canvas>
  <body>
      <button id="refresh" onclick="refresh();">Go</button>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script>
  var canvas = document.querySelector("canvas"),
      context = canvas.getContext("2d"),
      width = canvas.width,
      height = canvas.height;

  var jsonNodes;

  function refresh(){
    jsonNodes =  {
    "nodes": [
      {"id": "Myriel", "group": 1},
      {"id": "Napoleon", "group": 1},
      {"id": "Mlle.Baptistine", "group": 1} ],
      "links": [
      {"source": "Napoleon", "target": "Myriel", "value": 1} ]
       } ;

        simulation
        .nodes(jsonNodes.nodes)
        .force("link")
        .links(jsonNodes.links);   
  };

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

  d3.json("../data/miserables.json", function(error, graph) {
    if (error) throw error;

    simulation
        .nodes(graph.nodes)
        .on("tick", ticked);

    simulation.force("link")
        .links(graph.links);

    d3.select(canvas)
        .call(d3.drag()
            .container(canvas)
            .subject(dragsubject));

    function ticked() {
      var margin = 20;
      graph.nodes.forEach(function(d) { 
        d.x = Math.max(margin, Math.min(width - margin, d.x))
        d.y = Math.max(margin, Math.min(height - margin, d.y))
      })

      context.clearRect(0, 0, width, height);

      context.beginPath();
      graph.links.forEach(drawLink);
      context.strokeStyle = "#aaa";
      context.stroke();

      context.beginPath();
      graph.nodes.forEach(drawNode);
      context.fill();
      context.strokeStyle = "#fff";
      context.stroke();
    }

    function dragsubject() {
      return simulation.find(d3.event.x, d3.event.y);
    }
  });

  function drawLink(d) {
    context.moveTo(d.source.x, d.source.y);
    context.lineTo(d.target.x, d.target.y);
  }

  function drawNode(d) {
    context.moveTo(d.x + 3, d.y);
    context.arc(d.x, d.y, 3, 0, 2 * Math.PI);
  }
  </script>
  </body>

去
var canvas=document.querySelector(“canvas”),
context=canvas.getContext(“2d”),
宽度=画布宽度,
高度=画布高度;
var-jsonNodes;
函数刷新(){
jsonNodes={
“节点”:[
{“id”:“Myriel”,“group”:1},
{“id”:“拿破仑”,“集团”:1},
{“id”:“Mlle.Baptistine”,“group”:1}],
“链接”:[
{“来源”:“拿破仑”,“目标”:“米里哀”,“价值”:1}]
} ;
模拟
.nodes(jsonNodes.nodes)
.force(“链接”)
.links(jsonNodes.links);
};
var simulation=d3.forceSimulation()
.force(“link”,d3.forceLink().id(函数(d){return d.id;}))
.force(“电荷”,d3.forceManyBody())
.力(“中心”,d3.力中心(宽度/2,高度/2));
d3.json(“../data/miserables.json”),函数(错误,图形){
如果(错误)抛出错误;
模拟
.nodes(图.nodes)
。在(勾选)上;
模拟力(“链接”)
.links(图形链接);
d3.选择(画布)
.call(d3.drag()
.容器(帆布)
.主题(dragsubject));
函数勾选(){
var保证金=20;
forEach(函数(d){
d、 x=数学最大值(边距,数学最小值(宽度-边距,d.x))
d、 y=数学最大值(边距,数学最小值(高度-边距,d.y))
})
clearRect(0,0,宽度,高度);
context.beginPath();
图.links.forEach(drawLink);
context.strokeStyle=“#aaa”;
stroke();
context.beginPath();
graph.nodes.forEach(drawNode);
context.fill();
context.strokeStyle=“#fff”;
stroke();
}
函数dragsubject(){
返回模拟.find(d3.event.x,d3.event.y);
}
});
功能拉杆(d){
context.moveTo(d.source.x,d.source.y);
lineTo(d.target.x,d.target.y);
}
功能节点(d){
上下文。移动到(d.x+3,d.y);
弧(d.x,d.y,3,0,2*Math.PI);
}

根据您更新的文章中的示例代码,很少有事情会导致无法达到预期的结果。 首先,我可以看到jsonNodes已经是所需格式的对象。 其次,由于变量中的数据已经是所需的格式,因此不需要使用
d3.json(“../data/miserables.json”)函数(error,graph)对其进行解析{
如果(错误)抛出错误;

同样在Andrew Reid的例子中,他使用了对象
,在您的例子中,它将
jsonNodes
。因此,在任何地方,您都可以看到
图.节点
图.链接
将其替换为
jsonNodes.节点
jsonNodes.链接
。这是更改所有单独位置的更简单的替代方法s是将数据从
jsonNodes
传输到名为
graph
的变量,并使用
graph
变量,如Andrew Reid的示例所示

最后,您声明模拟的顺序是错误的。您正在呼叫

    simulation
        .nodes(jsonNodes.nodes)
        .force("link")
        .links(jsonNodes.links);   
  };
以前

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

这是一款为您准备好一切的plunker:

其他一些示例:直接使用变量中的数据。但是,请记住,此示例使用d3 v3,并且力模拟的语法已更改。还有许多示例直接在力模拟中使用变量: 您可以使用搜索更多示例


我希望这有帮助。如果没有,请创建plunker/block,让我检查您的操作是否正确。并将更多数据填充到jsonNodes变量中。

jsonNodes是全局变量吗?您能否发布一段更完整的代码,以便我们知道您的位置。