捕获/保存d3.js可视化的当前状态

时间:2015-11-11 06:53:45

标签: javascript d3.js

我是D3的新手,我正在寻找一个简单的艺术应用程序,允许用户在自定义背景上删除d3数据点,在此过程中创建艺术。

用户放下每个D3节点后,是否可以保存每个D3节点的位置,这样当重新加载页面时,所有节点都会迁移回其位置?

非常感谢任何帮助!谢谢!

2 个答案:

答案 0 :(得分:4)

您没有提到您使用的d3布局。无论如何,只收集绑定到节点和链接的数据就可以完成这项工作。这是工作代码段。

1)更新图表。 2)清除图表。 3)加载包含更新的图表。

希望这有帮助。

var initialData = {
  "nodes":[
    {"name":"Myriel","group":1},
    {"name":"Napoleon","group":1},
    {"name":"Mlle.Baptistine","group":1},
    {"name":"Mme.Magloire","group":1},
    {"name":"CountessdeLo","group":1},
    {"name":"Geborand","group":1},
    {"name":"Champtercier","group":1},
    {"name":"Cravatte","group":1},
    {"name":"Count","group":1}    
  ],
  "links":[
    {"source":1,"target":0,"value":1},
    {"source":2,"target":0,"value":8},
    {"source":3,"target":0,"value":10},
    {"source":3,"target":2,"value":6},
    {"source":4,"target":0,"value":1}    
  ]
};
var width = 960,
    height = 500;

var color = d3.scale.category20();

var force = d3.layout.force()
    .charge(-120)
    .linkDistance(30)
    .size([width, height]);

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

draw(initialData);
var link, node;
function draw(graph){
  force
      .nodes(graph.nodes)
      .links(graph.links)
      .start();

  link = svg.selectAll(".link")
      .data(graph.links)
    .enter().append("line")
      .attr("class", "link")
      .style("stroke-width", function(d) { return Math.sqrt(d.value); });

var drag = force.drag()
    .on("dragstart", dragstart);

  node = svg.selectAll(".node")
      .data(graph.nodes)
    .enter().append("circle")
      .attr("class", "node")
      .attr("r", 5)
      .style("fill", function(d) { return color(d.group); })
      .call(drag);

  node.append("title")
      .text(function(d) { return d.name; });

  force.on("tick", function() {
    link.attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });

    node.attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });
  });

function dragstart(d) {
  d.x = d3.event.x;
  d.y = d3.event.y;
  d3.select(this).classed("fixed", d.fixed = true);
}
  }
var savedGraph = { nodes: [], links: [] };
d3.select("#saveBtn").on('click',function(){
  savedGraph.nodes = node.data();
  savedGraph.links = link.data(); 
  svg.selectAll("*").remove();
});
d3.select("#loadBtn").on('click',function(){    
  console.log(savedGraph);
  draw(savedGraph);
});
.node {
  stroke: #fff;
  stroke-width: 1.5px;
}

.link {
  stroke: #999;
  stroke-opacity: .6;
}
<script src="https://d3js.org/d3.v3.min.js"></script>
<input type="button" value="Clear" id="saveBtn"/>
<input type="button" value="Load" id="loadBtn"/>

答案 1 :(得分:2)

我不知道D3中的持久性库,因此您可能需要以自己的方式持久化。

如果您只关心位置,那么您只需创建一个位置数组,即var positions = [ { x: x1, y: y1 }, { x: x2, y: y2 }, ... ],您可以选择将此数据发送到服务器,或者保留在浏览器的本地存储中,如果只需在特定的浏览器上保留它就可以了,例如

// persist
window.localStorage.setItem('positions',JSON.stringify(positions));

// When the page is loaded
var positions = JSON.parse(window.localStorage.getItem('positions'));

然后您可以使用这些位置重绘所有节点。