d3.jsにおける配列の参照について
現在( http://bl.ocks.org/tag1216/76e6bba3fd1784eba83c )こちらのソースを参考にさせて頂きプログラムを作成しております。
その中で
d3.json("https://qiita.com/api/v1/items?per_page=100", function(error, items) {
var index = 0;
var timer = setInterval(function() {
try {
if (items.length <= index) {
clearInterval(timer);
showMessage("");
return;
}
showMessage("データ追加中(" + (index+1) + "/" + items.length + ")...");
appendItem(items[index++])
}
catch (e) {
showMessage(e);
clearInterval(timer);
}
}, APPEND_INTERVAL);
});
この部分の記述についてお伺いしたいことがあります。
現在私が作成しているプログラムでは
d3.json("https://qiita.com/api/v1/items?per_page=100", function(error, items) {
この部分のurlで提供しているjsonファイルの代わりに、プログラム自体でローカルな配列を作りその中に類似した情報を格納しています。
url部分にローカル変数である配列を格納したい場合どのように記述すれば正常に動かすことができますでしょうか?
d3.jsのAPIページ( https://github.com/mbostock/d3/wiki/API-%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9 )を探してみたのですが有効な手立てを見つけることが出来ませんでした。
この記述のようにローカルな配列へのアクセスの仕方を探しております。お力添えの方よろしくお願い致します。
追記:
<!DOCTYPE html>
<html lang="ja">
<style>
svg {
border: solid 1px;
}
.node circle {
stroke: #000;
stroke-width: .5px;
opacity: .7;
}
.node text {
pointer-events: none;
font-size: 8px;
}
.node .shadow {
stroke: #fff;
stroke-width: 3px;
stroke-opacity: .7;
}
.node .text {
}
.link {
stroke: #888;
opacity: .3;
}
</style>
<head>
<meta charset="utf-8">
<title>D3.js(Force Layout)の練習</title>
</head>
<body>
<script src="http://d3js.org/d3.v3.js" charset="utf-8"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script>
function pointer(){
var object = document.getElementById('object');
if (object.contentDocument)
var svgdoc = object.getSVGDocument();
var svgelm = svgdoc.documentElement.style.cursor='pointer';
}
var WIDTH = 800,
HEIGHT = 800,
TAG_IMAGE_SIZE = 16,
ITEM_IMAGE_SIZE = 8,
APPEND_INTERVAL = 250;
var nodes = [];
var links = [];
var xlink = [];
var link2 = [];
var tags = [];
var items = [];
var Tag = [];
var nodes2 = [];
var links2 = [];
var color = d3.scale.category20();
var NAME_PREFIX = "_";
/* var url = "https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/hatena/b/hotentry&num=-1";
var proxy_url = "http://allow-any-origin.appspot.com/" + encodeURIComponent(url); */
function for_each(array, func){ Array.prototype.forEach.call(array, func); }
function get_html(callback){
var hatena_hotentry_url = "http://b.hatena.ne.jp/hotentry";
hatena_hotentry_url = "http://allow-any-origin.appspot.com/"
+ encodeURIComponent(hatena_hotentry_url);
/* var hatena_hotentry_url = "./hatena_hotentry.html" */
var req = new XMLHttpRequest();
req.open("GET", hatena_hotentry_url);
req.onreadystatechange = function() {
if (req.readyState === 4 && req.status === 200) {
callback(req.responseText);
req = undefined;
}
};
req.send(null);
}
function html_to_relation(html){
var doc = new DOMParser().parseFromString(html, "text/html");
var error_tags = doc.getElementsByTagName("parsererror");
if(error_tags.length){
console.log("error: ", error_tags);
return [["Parse error", "Maybe HTML is broken"]];
}
var relation = []; /*// [["name", ...], ...]
*/ var entry_elms = doc.querySelectorAll(
"[data-track-section='default'] .entry-contents");
for_each(entry_elms, function(entry_elm){
var entry_link_elm = entry_elm.querySelector(".entry-link");
if(!entry_link_elm){ return; }
var name_array = [];
relation.push(name_array);
name_array.push(entry_link_elm.href);
name_array.push(entry_link_elm.title);
var entry_meta_elm = entry_elm.nextElementSibling;
if(!entry_meta_elm){ return; }
for_each(entry_meta_elm.querySelectorAll("a.tag"), function(tag_elm){
name_array.push(tag_elm.textContent);
});
});
return relation;
}
function relation_view(relation){
var d = [];
var normal = [];
for(var i = 0;i<relation.length;i++){
if(i+1 < relation.length){
var num ={"source": i ,"target": + (i+1) };
}else{
var num ={"source": i , "target": 0};
}
var sub1 = relation[i][2];
var sub2 = relation[i][3];
var sub3 = relation[i][4];
var sub4 = relation[i][5];
var a1 = {"name":sub1,"url":'http://b.hatena.ne.jp/search/tag?q=' + sub1};
var a2 = {"name":sub2,"url":'http://b.hatena.ne.jp/search/tag?q=' + sub2};
var a3 = {"name":sub3,"url":'http://b.hatena.ne.jp/search/tag?q=' + sub3};
var a4 = {"name":sub4,"url":'http://b.hatena.ne.jp/search/tag?q=' + sub4};
var c = [];
c.push(a2,a3,a4);
normal.push(a2,a3,a4);
/* a.push(sub1,sub2,sub3,sub4); */
var list = {"label": relation[i][1] , "url": relation[i][0],
"tags":c};
nodes.push(list);
links.push(num);
};
console.log(nodes)
showMessage("データ読み込み中");
showMessage("データ読み込み中");
items = nodes;
var index = 0;
var timer = setInterval(function(){
try{
if(items.length <= index){
clearInterval(timer);
shoMessage("");
return;
}
showMessage("データ追加中(" + (index + 1) + "/" + items.length + ")");
appendItem(nodes[index++])
console.log(items[index++])
}
catch(e){
showMessage(e);
clearInterval(timer);
}
},APPEND_INTERVAL);
// };
function appendItem(item){
items.push(item);
console.log(items)
nodes2.push(item);
console.log(nodes2)
item.tags.forEach(function(tag){
var name = NAME_PREFIX + tag.name;
if(!(name in tags)){
tags[name] = tag;
tags[name].count = 0;
nodes2.push(tags[name]);
}
tags[name].count++;
links2.push({
source:nodes2.indexOf(item),
target:nodes2.indexOf(tags[name])
});
});
restart();
}
var svg = d3.select("body").append("svg")
.attr("width", WIDTH)
.attr("height", HEIGHT);
var force = d3.layout.force()
.size([WIDTH, HEIGHT])
.nodes(nodes)
.links(links)
.charge(0)
.linkDistance(20)
.linkStrength(1)
.gravity(0.3)
.start();
var itemNode = svg.selectAll(".item-node");
var tagNode = svg.selectAll(".tag-node");
var link = svg.selectAll(".link")
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; });
itemNode.attr("transform", function(d) {return "translate(" + d.x + "," + d.y + ")"; });
tagNode.attr("transform", function(d) {return "translate(" + d.x + "," + d.y + ")"; });
});
function showMessage(text) {
d3.select(".message").text(text);
}
/* var tags = nodes.reduce(function(tags,item){ */
function restart(){
itemNode = itemNode.data(items);
tagNode = tagNode.data(d3.values(tags));
drawItemNode();
drawTagNode();
darawLink();
force
.nodes(nodes2)
.links(links2)
.charge(function(d){
return d.count ? -(d.count * 200) : -100;
})
force.start();
}
function drawItemNode(){
var g = itemNode.enter().append('g')
.attr('class','node item')
.call(force.drag);
var a = g.append("a")
.attr('xlink:href',function(d){return 'http://b.hatena.ne.jp/search/tag?q=' + d.name;})
.attr('target','_blank');
a.append("circle")
.attr("r",ITEM_IMAGE_SIZE);
a.append("image")
.attr("xlink:href",function(d){return image_url;})
.attr({ x: -ITEM_IMAGE_SIZE/2,
y: -ITEM_IMAGE_SIZE/2,
width: ITEM_IMAGE_SIZE,
height: ITEM_IMAGE_SIZE
});
}
function drawTagNode(){
var g= tagNode.enter().insert("g","item")
.attr("class","node tag")
.call(force.drag);
var a = g.append("a")
.attr('xlink:href',function(d){return 'http://b.hatena.ne.jp/search/tag?q=' + d.name;})
.attr('target','_blank');
a.append("image")
.attr("xlink:href",function(d){
return d.icon_url == "/icons/medium/missing.png"
? "http://qiita.com/icons/medium/missing.png"
: d.icon_url;
});
a.append("rect");
a.append("text")
.attr("class", "shadow");
a.append("text")
.attr("class", "text");
tagNode.selectAll("text")
.attr("text-anchor", "middle")
.text(function(d) {return d.name;});
tagNode.each(function(d) {
var size = ~~(TAG_IMAGE_SIZE * Math.sqrt(d.count));
d3.select(this).select("image")
.attr({
x: -size/2,
y: -size/2,
width: size,
height: size
});
d3.select(this).select("rect")
.attr({
x: -size/2,
y: -size/2,
width: size,
height: size
});
d3.select(this).selectAll("text")
.attr("dy", size / 2 + 10);
});
}
function drawLink(){
link = link.data(links2);
link.enter().insert("line","tag")
.attr("class","link");
}
}
get_html(function(html){ relation_view(html_to_relation(html)); });
</script>
</body>
</html></html>
自分なりに変更を加えてみたのですが、参考にしているプログラムがindex++で順にonjectが増えている一方私の作成したものは一気にnodes.lengthの49までobjectが追加されてしまう上、forEachの部分で1から順にすべての要素が参照されるのではなく最初の要素のみで処理が止まってしまいます。
これはどの部分を修正すれば良いのでしょうか?
宜しくお願い致します。