带有JSON的D3.js树图动态更新

时间:2019-02-12 01:02:51

标签: javascript d3.js

使用下面的以下代码,我从一个客户端接收JSON数据包,在此我希望能够在接收到新的JSON数据包时动态更新树形图。为了简单起见,现在我只是尝试从给定的JSON更新一个值。我感谢您的帮助!我通过CodePen(下面的JS)获得了这段代码

var treeData = {
  name: "T",
  children: [
    {
      name: "A",
      children: [
        { name: "A1" },
        { name: "A2" },
        { name: "A3" },
        {
          name: "C",

          children: [
            { name: "C1" },
            {
              name: "D",
              children: [{ name: "D1" }, { name: "D2" }]
            }
          ]
        }
      ]
    },
    { name: "Z" },
    {
      name: "B",
      children: [{ name: "B1" }, { name: "B2" }, { name: "B3" }]
    }
  ]
};

var margin = { top: 20, right: 90, bottom: 30, left: 90 },
  width = 960 - margin.left - margin.right,
  height = 500 - margin.top - margin.bottom;
var svg = d3
  .select("body")
  .append("svg")
  .attr("width", width + margin.right + margin.left)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var i = 0,
  duration = 750,
  root;
var treemap = d3.tree().size([height, width]);
root = d3.hierarchy(treeData, function(d) {
  return d.children;
});
root.x0 = height / 2;
root.y0 = 0;
root.children.forEach(collapse);

update(root);
function collapse(d) {
  if (d.children) {
    d._children = d.children;
    d._children.forEach(collapse);
    d.children = null;
  }
}

function update(source) {
  var treeData = treemap(root);
  var nodes = treeData.descendants(),
    links = treeData.descendants().slice(1);
  nodes.forEach(function(d) {
    d.y = d.depth * 180;
  });
  var node = svg.selectAll("g.node").data(nodes, function(d) {
    return d.id || (d.id = ++i);
  });
  var nodeEnter = node
    .enter()
    .append("g")
    .attr("class", "node")
    .attr("transform", function(d) {
      return "translate(" + source.y0 + "," + source.x0 + ")";
    })
    .on("click", click);
  nodeEnter
    .attr("class", "node")
    .attr("r", 1e-6)
    .style("fill", function(d) {
      return d.parent ? "rgb(39, 43, 77)" : "#fe6e9e";
    });
  nodeEnter
    .append("rect")
    .attr("rx", function(d) {
      if (d.parent) return d.children || d._children ? 0 : 6;
      return 10;
    })
    .attr("ry", function(d) {
      if (d.parent) return d.children || d._children ? 0 : 6;
      return 10;
    })
    .attr("stroke-width", function(d) {
      return d.parent ? 1 : 0;
    })
    .attr("stroke", function(d) {
      return d.children || d._children
        ? "rgb(3, 192, 220)"
        : "rgb(38, 222, 176)";
    })
    .attr("stroke-dasharray", function(d) {
      return d.children || d._children ? "0" : "2.2";
    })
    .attr("stroke-opacity", function(d) {
      return d.children || d._children ? "1" : "0.6";
    })
    .attr("x", 0)
    .attr("y", -10)
    .attr("width", function(d) {
      return d.parent ? 40 : 20;
    })
    .attr("height", 20);

  nodeEnter
    .append("text")
    .style("fill", function(d) {
      if (d.parent) {
        return d.children || d._children ? "#ffffff" : "rgb(38, 222, 176)";
      }
      return "rgb(39, 43, 77)";
    })
    .attr("dy", ".35em")
    .attr("x", function(d) {
      return d.parent ? 20 : 10;
    })
    .attr("text-anchor", function(d) {
      return "middle";
    })
    .text(function(d) {
      return d.data.name;
    });

  var nodeUpdate = nodeEnter.merge(node);

  nodeUpdate
    .transition()
    .duration(duration)
    .attr("transform", function(d) {
      return "translate(" + d.y + "," + d.x + ")";
    });
  var nodeExit = node
    .exit()
    .transition()
    .duration(duration)
    .attr("transform", function(d) {
      return "translate(" + source.y + "," + source.x + ")";
    })
    .remove();
  nodeExit.select("rect").style("opacity", 1e-6);
  nodeExit.select("rect").attr("stroke-opacity", 1e-6);
  nodeExit.select("text").style("fill-opacity", 1e-6);
  var link = svg.selectAll("path.link").data(links, function(d) {
    return d.id;
  });
  var linkEnter = link
    .enter()
    .insert("path", "g")
    .attr("class", "link")
    .attr("d", function(d) {
      var o = { x: source.x0, y: source.y0 };
      return diagonal(o, o);
    });
  var linkUpdate = linkEnter.merge(link);
  linkUpdate
    .transition()
    .duration(duration)
    .attr("d", function(d) {
      return diagonal(d, d.parent);
    });
  var linkExit = link
    .exit()
    .transition()
    .duration(duration)
    .attr("d", function(d) {
      var o = { x: source.x, y: source.y };
      return diagonal(o, o);
    })
    .remove();
  nodes.forEach(function(d) {
    d.x0 = d.x;
    d.y0 = d.y;
  });
  function diagonal(s, d) {
    path = `M ${s.y} ${s.x}
            C ${(s.y + d.y) / 2} ${s.x},
              ${(s.y + d.y) / 2} ${d.x},
              ${d.y} ${d.x}`;

    return path;
  }
  function click(d) {
    if (d.children) {
      d._children = d.children;
      d.children = null;
    } else {
      d.children = d._children;
      d._children = null;
    }
    update(d);
  }
}

这是我的代码,用于在下面获取JSON数据。我正在接收JSON数据,但是,在接收JSON数据包时,我成功尝试更新树形图。谢谢您的光临和垂涎!

var treeData1;
var margin = { top: 20, right: 90, bottom: 30, left: 90 },
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var svg = d3
.select("body")
.append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var i = 0,
duration = 750,
root;
var treemap = d3.tree().size([height, width]);

var czmlStreamUrl = '/sse';
var czmlEventSource = new EventSource(czmlStreamUrl);   
czmlEventSource.addEventListener('server-time', function (e) {
  lastMessage = e.data;
  try{ customParse(JSON.parse(e.data));} catch(e) {console.log('error from incoming stream',e)}

});

var cart = 0;

function customParse(dataAsJSON) {
// OBTAIN QUATERNION
var arrQuat = dataAsJSON[1].orientation.unitQuaternion;
// OBTAIN CARTESIAN
var arrCart = dataAsJSON[1].position.cartesian;
// SLICE QUATERNION DATA
arrQuat = arrQuat.slice(1, 5);
cart = arrQuat[1];
// SLICE CARTESTIAN DATA
arrCart = arrCart.slice(1, 4);
// CONVERT CARTESIAN FROM METERS TO KM
for(i=0;i<arrCart.length;i++)
{
  arrCart[i] = arrCart[i]/1000;
}

  var treeData1 = {
    name: "Sat",
    children: [
      {
        name: "ADCS",
        children: [
          { name: cart },
          { name: "A2" },
          { name: "A3" },
          {
            name: "C",

            children: [
              { name: "C1" },
              {
                name: "D",
                children: [{ name: "D1" }, { name: "D2" }]
              }
            ]
          }
        ]
      },
      { name: "EPS" },
      {
        name: "TT&C",
        children: [{ name: "B1" }, { name: "B2" }, { name: "B3" }]
      }
    ]
  };

  getTreeJson(treeData1);
}

function getTreeJson(jsondata)
{
  // load the external data
  root = d3.hierarchy(jsondata, function(d) {
    return d.children;
    });
    update(root);

  // TRIED THIS BUT UNSUCCESSFUL
  /*d3.json(jsondata, function(error, treeData) {
    root = treeData;
  });*/
}

root.x0 = height / 2;
root.y0 = 0;
root.children.forEach(collapse);


function collapse(d) {
  if (d.children) {
    d._children = d.children;
    d._children.forEach(collapse);
    d.children = null;
  }
}

function update(source) {
  var treeData = treemap(root);
  var nodes = treeData.descendants(),
    links = treeData.descendants().slice(1);
  nodes.forEach(function(d) {
    d.y = d.depth * 180;
  });
  var node = svg.selectAll("g.node").data(nodes, function(d) {
    return d.id || (d.id = ++i);
  });
  var nodeEnter = node
    .enter()
    .append("g")
    .attr("class", "node")
    .attr("transform", function(d) {
      return "translate(" + source.y0 + "," + source.x0 + ")";
    })
    .on("click", click);
  nodeEnter
    .attr("class", "node")
    .attr("r", 1e-6)
    .style("fill", function(d) {
      return d.parent ? "rgb(39, 43, 77)" : "#fe6e9e";
    });
  nodeEnter
    .append("rect")
    .attr("rx", function(d) {
      if (d.parent) return d.children || d._children ? 0 : 6;
      return 10;
    })
    .attr("ry", function(d) {
      if (d.parent) return d.children || d._children ? 0 : 6;
      return 10;
    })
    .attr("stroke-width", function(d) {
      return d.parent ? 1 : 0;
    })
    .attr("stroke", function(d) {
      return d.children || d._children
        ? "rgb(3, 192, 220)"
        : "rgb(38, 222, 176)";
    })
    .attr("stroke-dasharray", function(d) {
      return d.children || d._children ? "0" : "2.2";
    })
    .attr("stroke-opacity", function(d) {
      return d.children || d._children ? "1" : "0.6";
    })
    .attr("x", 0)
    .attr("y", -10)
    .attr("width", function(d) {
      return d.parent ? 40 : 20;
    })
    .attr("height", 20);

  nodeEnter
    .append("text")
    .style("fill", function(d) {
      if (d.parent) {
        return d.children || d._children ? "#ffffff" : "rgb(38, 222, 176)";
      }
      return "rgb(39, 43, 77)";
    })
    .attr("dy", ".35em")
    .attr("x", function(d) {
      return d.parent ? 20 : 10;
    })
    .attr("text-anchor", function(d) {
      return "middle";
    })
    .text(function(d) {
      return d.data.name;
    });

  var nodeUpdate = nodeEnter.merge(node);

  nodeUpdate
    .transition()
    .duration(duration)
    .attr("transform", function(d) {
      return "translate(" + d.y + "," + d.x + ")";
    });
  var nodeExit = node
    .exit()
    .transition()
    .duration(duration)
    .attr("transform", function(d) {
      return "translate(" + source.y + "," + source.x + ")";
    })
    .remove();
  nodeExit.select("rect").style("opacity", 1e-6);
  nodeExit.select("rect").attr("stroke-opacity", 1e-6);
  nodeExit.select("text").style("fill-opacity", 1e-6);
  var link = svg.selectAll("path.link").data(links, function(d) {
    return d.id;
  });
  var linkEnter = link
    .enter()
    .insert("path", "g")
    .attr("class", "link")
    .attr("d", function(d) {
      var o = { x: source.x0, y: source.y0 };
      return diagonal(o, o);
    });
  var linkUpdate = linkEnter.merge(link);
  linkUpdate
    .transition()
    .duration(duration)
    .attr("d", function(d) {
      return diagonal(d, d.parent);
    });
  var linkExit = link
    .exit()
    .transition()
    .duration(duration)
    .attr("d", function(d) {
      var o = { x: source.x, y: source.y };
      return diagonal(o, o);
    })
    .remove();
  nodes.forEach(function(d) {
    d.x0 = d.x;
    d.y0 = d.y;
  });
  function diagonal(s, d) {
    path = `M ${s.y} ${s.x}
            C ${(s.y + d.y) / 2} ${s.x},
              ${(s.y + d.y) / 2} ${d.x},
              ${d.y} ${d.x}`;

    return path;
  }
  function click(d) {
    if (d.children) {
      d._children = d.children;
      d.children = null;
    } else {
      d.children = d._children;
      d._children = null;
    }
    update(d);
  }
}

0 个答案:

没有答案