2015-11-11 31 views
1

我是D3的新手,並且正在構建一個簡單的藝術應用程序,允許用戶在自定義背景上放置d3數據點,在過程中創建藝術。捕獲/保存d3.js可視化的當前狀態

是否有可能在用戶丟棄每個D3節點後保存每個D3節點的位置,這樣當頁面重新加載時,所有節點都將遷移回它們的位置?

任何幫助在這裏非常感謝!謝謝!

回答

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')); 

然後,您可以使用位置來重繪所有節點。

+0

謝謝@Natural林!確實非常有用! –

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"/>

+0

哇@吉爾沙,這是非常有幫助的。非常感謝。今天我開展了一項後續工作,同時確定了一個不同但類似的項目。是否可以在地圖盒地圖上放置d3節點並保留數據。而不是x,y座標,lat,long需要被捕獲。你認爲最好的辦法是做什麼? –