ノードのデータをグラフに非同期的に入力しようとしています。
非同期にフェッチされたデータが実際にグラフにバインドされ、準備ができたらレンダリングされるようにするにはどうすればよいですか?
まず、グラフ構造、ノード、およびリンクをレンダリングします。次に、データの準備ができたら、データをノードのプロパティとしてレンダリングします。新しいノードは、親のノードと対話することによって動的に追加でき、ノードのプロパティの完了を待ちたくありません。
Vivagraph.js ライブラリを使用していることに注意してください。graph
はライブラリで作成されたオブジェクトでaddLinks()
ありgetNode()
、その関数のプロパティです - Vivagraph demoのデモを参照してください。私はそれを私の試みの下書きとして使用しています。
私が経験した問題は、ノードが追加されるとすぐにノードがグラフにレンダリングされることです - addNode()またはaddLinks(node1, node2)関数 - 一方、ノードのプロパティは非同期的にフェッチされます - getNode(node).property = updatedValue - 結果はundefinedです。
EDITED -コメントに基づく簡略化されたコード
以下に、この (素晴らしい) ライブラリの作成者である @Anvaka が提供するチュートリアルに基づいた、実用的なモックアップ バージョンを含めます。
私の目標は、グラフをすぐにレンダリングして対話を可能にし、サード パーティから取得している間にデータを更新することです。
// attempt 1: fetch data async
var fetchInfo = function (graph, nodeId) {
var root = 'http://jsonplaceholder.typicode.com';
$.ajax({
url: root + '/photos/' + nodeId,
method: 'GET'
}).then(function (data) {
graph.getNode(nodeId).data = data.thumbnailUrl;
console.log(graph.getNode(nodeId));
});
};
// attempt 2: defer ajax directly
var fetchInfo_2 = function (graph, nodeId) {
var root = 'http://jsonplaceholder.typicode.com';
return $.ajax({
url: root + '/photos/' + nodeId,
method: 'GET'
});
};
function main() {
// As in previous steps, we create a basic structure of a graph:
var graph = Viva.Graph.graph();
graph.addLink(1, 2);
fetchInfo(graph, 1); // updated data is undefined when graph is rendered
fetchInfo(graph, 2); // updated data is undefined when graph is rendered
/* trying a different outcome by deferring whole ajax
graph.getNode(1).data = fetchInfo_2(1).done(function(data) {
data.thumbnailUrl;
}); // the whole object is deferred but cannot fetch data
graph.getNode(2).data = fetchInfo_2(2).done(function(data) {
data.thumbnailUrl;
}); // the whole object is deferred but cannot fetch data
*/
var graphics = Viva.Graph.View.svgGraphics(),
nodeSize = 24,
addRelatedNodes = function (nodeId, isOn) {
for (var i = 0; i < 6; ++i) {
var child = Math.floor((Math.random() * 150) + nodeId);
// I add children and update data from external sources
graph.addLink(nodeId, child);
fetchInfo(graph, child);
}
};
// dynamically add nodes on mouse interaction
graphics.node(function (node) {
var ui = Viva.Graph.svg('image')
.attr('width', nodeSize)
.attr('height', nodeSize)
.link(node.data);
console.log('rendered', node.id, node.data);
$(ui).hover(function () {
// nodes are rendered; nodes' data is undefined
addRelatedNodes(node.id);
});
return ui;
}).placeNode(function (nodeUI, pos) {
nodeUI.attr('x', pos.x - nodeSize / 2).attr('y', pos.y - nodeSize / 2);
});
graphics.link(function (link) {
return Viva.Graph.svg('path')
.attr('stroke', 'gray');
}).placeLink(function (linkUI, fromPos, toPos) {
var data = 'M' + fromPos.x + ',' + fromPos.y +
'L' + toPos.x + ',' + toPos.y;
linkUI.attr("d", data);
})
var renderer = Viva.Graph.View.renderer(graph, {
graphics: graphics
});
renderer.run();
}
main();
svg {
width: 100%;
height: 100%;
}
<script src="https://rawgit.com/anvaka/VivaGraphJS/master/dist/vivagraph.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>