d3.js 树 - 节点的 CSV 属性
d3.js Tree - CSV Attributes to Nodes
我正在尝试制作一个我正在提取的文件的可视化表示 csv。
但是我好像和d3 Tree期望的结构碰壁了。
我的代码:
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="mydata.csv"></script>
<script>
var margin = {top: 20, right: 120, bottom: 20, left: 120},
width = 800 - margin.right - margin.left,
height = 500 - margin.top - margin.bottom;
var canvas = d3.select("body").append("svg")
.attr("width", 2000)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });
d3.csv("mydata.csv", function(data) {
var nested_data = d3.nest()
.key(function(d) { return d['Machine']; })
.key(function(d) { return d['Name']; })
.entries(data);
flare_data.key = "Flare";
flare_data.values = nested_data;
flare_data = reSortFlare(flare_data); //Turns Key Values into Name Children which D3 Tree expects
var nodes = tree.nodes(flare_data);
var link = canvas.selectAll(".link")
.data(tree.links(nodes))
.enter().append("path")
.attr("class", "link")
.attr("d", diagonal);
var node = canvas.selectAll(".node")
.data(nodes)
.enter()
.append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
node.append("circle")
.attr("r", 7);
node.append("text")
.attr("dx", function(d) { return d.children ? -15 : 15; })
.attr("dy", 3)
.style("text-anchor", function(d) { return d.children ? "end" : "start"; })
.text(function(d) { return d.children ? d.name : [d['URL Template'], d['xPath']]; });
});
function reSortFlare(root) {
//console.log("Calling");
for (var key in root) {
if (key == "key") {
root.name = root.key;
delete root.key;
}
if (key == "values") {
root.children = [];
for (item in root.values) {
root.children.push(reSortFlare(root.values[item]));
}
delete root.values;
}
}
return root;
}
</script>
我的 CSV 文件示例:
Machine,Name,URL Template,Page Start,Page Size,Max
Pages,xPath,RegEx,eCommerce,Search Interval,Additional Variable,Variable Value
"Machine [1]","eSearch - Web-GB","http://example.com/status","1","1","10","//somethingness","([0-9]{1,20})","1","0","Thum","true"
"Machine [1]","eSearch - Web-GB","http://forexample.com/randomness","1","1","10","//nothingness","([0-9]{1,20})","1","0","Kapool","true"
"Machine [1]","Web: Web-US","http://mangasite.com/mangacomic","1","1","10","//itemId","([0-9]{1,20})","1","0","Crawl Natural URL","true"
"Machine [1]","Web: Web-US","http://someothersite.fr/kapala","1","1","10","//itemId","([0-9]{1,20})","1","0","Block Sellers","true"
"Machine [1]","Link Test","http://kistergans.com/papals","0","1","1","//a/@href","(.*)","0","0",,
"Machine [1]","TW Search","https://mankini.jp/ofcourse","0","100","1","//a/@href","(.*/status/.*)","0","0",,
"Machine [1]","TW API","http://storagewars.com","0","1","1","//a/@href","(http.*)","0","0",,
"Machine [1]","Amiz Metaquery","http://www.Amiz.com/s/","1","10","1","//a[contains]/@href","(http://www\.Amiz\.com/","0","0",,
"Machine [1]","Amiz Metaquery Too","http://www.Amiz.de/s/?field-keywords=%q&page=%i","1","1","10","//div/@href","http://www.Amiz.de/).*","0","0",,
"Machine [2]","Subs.com","https://www.subs.com/search?f=%q&p=%i","0","1","10","//dt/a/@href","((https?://[^/]+)?/[^/\+]{10,500})","0","0",,
"Machine [2]","Extra.cc","http://extra.cc/search/","1","1","10","//a/@href","([^#]+)","0","0",,
"Machine [2]","Monitoring","http://monitoring.com/nothing","1","1","1","//nothing","(.*)","0","0",,
"Machine [2]","SM - abe.com - users","http://s.weibo.com/user/lamborghini","1","1","1","//div[@class=""person_detail""]/p[@class=""person_addr""]/a/@href","(.*)","0","0",,
"Machine [2]","SM - koko.com","http://i.youku.com/u_search/?page=%i&q=%q","1","1","10","//li[@class=""u_title""]/a/@href","(http://i.youku.com/u/.+)","0","0",,
"Machine [2]","Amiz.com Page","http://www.Amiz.com/s/?field-keywords=%q&page=%i","1","1","5","//div[@id=""rightResultsATF""]//@href","/dp/([^/]+)/.*","1","0",,
"Machine [3]","MA: Apple.com (iTunes)","http://software.com/aabc","0","200","1","//iTunesApp/trackViewUrl","(@keli)","1","0",,
"Machine [3]","MA: Wipple.com","http://kalamaza.ck/keywords","0","48","5","//a/@href","(http://abc.ck)","0","0",,
"Machine [3]","SM: Linkage.com ","http://stormborn.com/lalala","0","100","5","//a/@href","(lililo+)","0","0",,
"Machine [3]","SM: Afro.com - via SearchTool","http://lipidi.li/lili","0","1","1","//a/@href","(.*/status/[0-9]+)","0","0",,
"Machine [3]","SM: Afro.com","http://sazdarma.ka/yoyo","0","1","1","//a/@href","(.*/status/[0-9]+)","0","0",,
这会产生一个看起来像这样的树
我的问题是我需要每个机器的子节点(例如 "eSearch - Web-GB")有一个单独的节点用于(名称、URL 模板、页面开始、页面大小、最大页面等。 ).
但是对于 text 属性,虽然我可以 return 所有这些属性,但它们都是 return 用逗号分隔符组合在一起的,而不是作为单独的节点。
我已将代码加载到 JSFiddle,但似乎无法正常工作。
如有任何帮助,我们将不胜感激。
此外,是否有更简单的方法将 CSV 转换为正确的 JSON 格式?
var pre_data = d3.csv.parse(d3.select("pre#data").text());
//document.getElementsByTagName("BODY")[0].innerHTML = data;
var margin = {
top: 20,
right: 120,
bottom: 20,
left: 120
},
width = 1000 - margin.right - margin.left,
height = 500 - margin.top - margin.bottom;
var canvas = d3.select("body").append("svg")
.attr("width", 2000)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function (d) {
return [d.y, d.x];
});
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
//var nested_data = _.nest(csv_data, "Machine");
//var nodes = tree.nodes(nested_data);
var flare_data = {};
var nested_data = d3.nest()
.key(function (d) {
return d['Machine'];
})
.key(function (d) {
return d['Name'];
})
.entries(pre_data);
flare_data.key = "Flare";
flare_data.values = nested_data;
flare_data = reSortFlare(flare_data);
var nodes = tree.nodes(flare_data);
var link = canvas.selectAll(".link")
.data(tree.links(nodes))
.enter().append("path")
.attr("class", "link")
.attr("d", diagonal);
var node = canvas.selectAll(".node")
.data(nodes)
.enter()
.append("g")
.attr("class", "node")
.attr("transform", function (d) {
return "translate(" + d.y + "," + d.x + ")";
});
node.append("circle")
.attr("r", 7)
.on("mouseover", function (d) {
div.transition()
.duration(200)
.style("opacity", .9);
div.html(
"Name: " + (d.name?d.name:d["URL Template"]+(d.xPath.replace("//","/"))) + "<br/>" +
"URL Template: " + d['URL Template'] + "<br/>" +
"Page Start: " + d['Page Start'] + "<br/>" +
"Page Size: " + d['Page Size'] + "<br/>" +
"Max Pages: " + d['Max Pages'] + "<br/>" +
"xPath: " + d['xPath'] + "<br/>" +
"RegEx: " + d['RegEx'] + "<br/>" +
"eCommerce: " + d['eCommerce'] + "<br/>" +
"Search Interval: " + d['Search Interval'] + "<br/>" +
"Additional Variable: " + d['Additional Variable'] + "<br/>" +
"Variable Value: " + d['Variable Value'] + "<br/>")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("click", function (d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
node.append("text")
.attr("dx", function (d) {
return d.children ? -15 : 15;
})
.attr("dy", 3)
.style("text-anchor", function (d) {
return d.children ? "end" : "start";
})
.text(function (d) {
//return d.children ? d.name : d['Name'];
return d.children ? d.name : d["URL Template"]+(d.xPath.replace("//","/"));
});
function reSortFlare(d) {
//console.log("Calling");
for (var key in d) {
if (key == "key") {
d.name = d.key;
delete d.key;
}
if (key == "values") {
d.children = [];
for (var item in d.values) {
d.children.push(reSortFlare(d.values[item]));
}
delete d.values;
}
}
return d;
}
.node circle {
fill: #fff;
stroke: #4B9FC3;
stroke-width: 3px;
}
.node {
font: 12px sans-serif;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 2x;
}
div.tooltip {
position: absolute;
text-align: left;
width: 500px;
height: 200px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
pre {
display:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<body>
<pre id="data">Machine,Name,URL Template,Page Start,Page Size,Max Pages,xPath,RegEx,eCommerce,Search Interval,Additional Variable,Variable Value
"Machine [1]","eSearch - Web-GB","http://example.com/status","1","1","10","//somethingness","([0-9]{1,20})","1","0","Thum","true"
"Machine [1]","eSearch - Web-GB","http://forexample.com/randomness","1","1","10","//nothingness","([0-9]{1,20})","1","0","Kapool","true"
"Machine [1]","Web: Web-US","http://mangasite.com/mangacomic","1","1","10","//itemId","([0-9]{1,20})","1","0","Crawl Natural URL","true"
"Machine [1]","Web: Web-US","http://someothersite.fr/kapala","1","1","10","//itemId","([0-9]{1,20})","1","0","Block Sellers","true"
"Machine [1]","Link Test","http://kistergans.com/papals","0","1","1","//a/@href","(.*)","0","0",,
"Machine [1]","TW Search","https://mankini.jp/ofcourse","0","100","1","//a/@href","(.*/status/.*)","0","0",,
"Machine [1]","TW API","http://storagewars.com","0","1","1","//a/@href","(http.*)","0","0",,
"Machine [1]","Amiz Metaquery","http://www.Amiz.com/s/","1","10","1","//a[contains]/@href","(http://www\.Amiz\.com/","0","0",,
"Machine [1]","Amiz Metaquery Too","http://www.Amiz.de/s/?field-keywords=%q&page=%i","1","1","10","//div/@href","http://www.Amiz.de/).*","0","0",,
"Machine [2]","Subs.com","https://www.subs.com/search?f=%q&p=%i","0","1","10","//dt/a/@href","((https?://[^/]+)?/[^/\+]{10,500})","0","0",,
"Machine [2]","Extra.cc","http://extra.cc/search/","1","1","10","//a/@href","([^#]+)","0","0",,
"Machine [2]","Monitoring","http://monitoring.com/nothing","1","1","1","//nothing","(.*)","0","0",,
"Machine [2]","SM - abe.com - users","http://s.weibo.com/user/lamborghini","1","1","1","//div[@class=""person_detail""]/p[@class=""person_addr""]/a/@href","(.*)","0","0",,
"Machine [2]","SM - koko.com","http://i.youku.com/u_search/?page=%i&q=%q","1","1","10","//li[@class=""u_title""]/a/@href","(http://i.youku.com/u/.+)","0","0",,
"Machine [2]","Amiz.com Page","http://www.Amiz.com/s/?field-keywords=%q&page=%i","1","1","5","//div[@id=""rightResultsATF""]//@href","/dp/([^/]+)/.*","1","0",,
"Machine [3]","MA: Apple.com (iTunes)","http://software.com/aabc","0","200","1","//iTunesApp/trackViewUrl","(@keli)","1","0",,
"Machine [3]","MA: Wipple.com","http://kalamaza.ck/keywords","0","48","5","//a/@href","(http://abc.ck)","0","0",,
"Machine [3]","SM: Linkage.com ","http://stormborn.com/lalala","0","100","5","//a/@href","(lililo+)","0","0",,
"Machine [3]","SM: Afro.com - via SearchTool","http://lipidi.li/lili","0","1","1","//a/@href","(.*/status/[0-9]+)","0","0",,
"Machine [3]","SM: Afro.com","http://sazdarma.ka/yoyo","0","1","1","//a/@href","(.*/status/[0-9]+)","0","0",,</pre>
</body>
我想你正在寻找这个,如果没有请向我询问更多...
首先,您不需要 reSortFlare
函数。这可以通过更改 children accessor function.
来实现
var tree = d3.layout.tree()
.size([height, width])
.children(function(d){
return d.values;
});
其次,我相信你可以用.rollup
做你想做的事:
var nested_data = d3.nest()
.key(function(d) {
return d['Machine'];
})
.key(function(d) {
return d['Name'];
})
.rollup(function(d){
var children = [];
d.forEach(function(dSub){
for (var k in dSub){
if (k == 'URL Template' || k == 'xPath')
children.push({'key': dSub[k]})
}
})
return children;
})
.entries(data);
这会产生(示例 code here):
我正在尝试制作一个我正在提取的文件的可视化表示 csv。 但是我好像和d3 Tree期望的结构碰壁了。
我的代码:
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="mydata.csv"></script>
<script>
var margin = {top: 20, right: 120, bottom: 20, left: 120},
width = 800 - margin.right - margin.left,
height = 500 - margin.top - margin.bottom;
var canvas = d3.select("body").append("svg")
.attr("width", 2000)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });
d3.csv("mydata.csv", function(data) {
var nested_data = d3.nest()
.key(function(d) { return d['Machine']; })
.key(function(d) { return d['Name']; })
.entries(data);
flare_data.key = "Flare";
flare_data.values = nested_data;
flare_data = reSortFlare(flare_data); //Turns Key Values into Name Children which D3 Tree expects
var nodes = tree.nodes(flare_data);
var link = canvas.selectAll(".link")
.data(tree.links(nodes))
.enter().append("path")
.attr("class", "link")
.attr("d", diagonal);
var node = canvas.selectAll(".node")
.data(nodes)
.enter()
.append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
node.append("circle")
.attr("r", 7);
node.append("text")
.attr("dx", function(d) { return d.children ? -15 : 15; })
.attr("dy", 3)
.style("text-anchor", function(d) { return d.children ? "end" : "start"; })
.text(function(d) { return d.children ? d.name : [d['URL Template'], d['xPath']]; });
});
function reSortFlare(root) {
//console.log("Calling");
for (var key in root) {
if (key == "key") {
root.name = root.key;
delete root.key;
}
if (key == "values") {
root.children = [];
for (item in root.values) {
root.children.push(reSortFlare(root.values[item]));
}
delete root.values;
}
}
return root;
}
</script>
我的 CSV 文件示例:
Machine,Name,URL Template,Page Start,Page Size,Max
Pages,xPath,RegEx,eCommerce,Search Interval,Additional Variable,Variable Value
"Machine [1]","eSearch - Web-GB","http://example.com/status","1","1","10","//somethingness","([0-9]{1,20})","1","0","Thum","true"
"Machine [1]","eSearch - Web-GB","http://forexample.com/randomness","1","1","10","//nothingness","([0-9]{1,20})","1","0","Kapool","true"
"Machine [1]","Web: Web-US","http://mangasite.com/mangacomic","1","1","10","//itemId","([0-9]{1,20})","1","0","Crawl Natural URL","true"
"Machine [1]","Web: Web-US","http://someothersite.fr/kapala","1","1","10","//itemId","([0-9]{1,20})","1","0","Block Sellers","true"
"Machine [1]","Link Test","http://kistergans.com/papals","0","1","1","//a/@href","(.*)","0","0",,
"Machine [1]","TW Search","https://mankini.jp/ofcourse","0","100","1","//a/@href","(.*/status/.*)","0","0",,
"Machine [1]","TW API","http://storagewars.com","0","1","1","//a/@href","(http.*)","0","0",,
"Machine [1]","Amiz Metaquery","http://www.Amiz.com/s/","1","10","1","//a[contains]/@href","(http://www\.Amiz\.com/","0","0",,
"Machine [1]","Amiz Metaquery Too","http://www.Amiz.de/s/?field-keywords=%q&page=%i","1","1","10","//div/@href","http://www.Amiz.de/).*","0","0",,
"Machine [2]","Subs.com","https://www.subs.com/search?f=%q&p=%i","0","1","10","//dt/a/@href","((https?://[^/]+)?/[^/\+]{10,500})","0","0",,
"Machine [2]","Extra.cc","http://extra.cc/search/","1","1","10","//a/@href","([^#]+)","0","0",,
"Machine [2]","Monitoring","http://monitoring.com/nothing","1","1","1","//nothing","(.*)","0","0",,
"Machine [2]","SM - abe.com - users","http://s.weibo.com/user/lamborghini","1","1","1","//div[@class=""person_detail""]/p[@class=""person_addr""]/a/@href","(.*)","0","0",,
"Machine [2]","SM - koko.com","http://i.youku.com/u_search/?page=%i&q=%q","1","1","10","//li[@class=""u_title""]/a/@href","(http://i.youku.com/u/.+)","0","0",,
"Machine [2]","Amiz.com Page","http://www.Amiz.com/s/?field-keywords=%q&page=%i","1","1","5","//div[@id=""rightResultsATF""]//@href","/dp/([^/]+)/.*","1","0",,
"Machine [3]","MA: Apple.com (iTunes)","http://software.com/aabc","0","200","1","//iTunesApp/trackViewUrl","(@keli)","1","0",,
"Machine [3]","MA: Wipple.com","http://kalamaza.ck/keywords","0","48","5","//a/@href","(http://abc.ck)","0","0",,
"Machine [3]","SM: Linkage.com ","http://stormborn.com/lalala","0","100","5","//a/@href","(lililo+)","0","0",,
"Machine [3]","SM: Afro.com - via SearchTool","http://lipidi.li/lili","0","1","1","//a/@href","(.*/status/[0-9]+)","0","0",,
"Machine [3]","SM: Afro.com","http://sazdarma.ka/yoyo","0","1","1","//a/@href","(.*/status/[0-9]+)","0","0",,
这会产生一个看起来像这样的树
我的问题是我需要每个机器的子节点(例如 "eSearch - Web-GB")有一个单独的节点用于(名称、URL 模板、页面开始、页面大小、最大页面等。 ). 但是对于 text 属性,虽然我可以 return 所有这些属性,但它们都是 return 用逗号分隔符组合在一起的,而不是作为单独的节点。
我已将代码加载到 JSFiddle,但似乎无法正常工作。
如有任何帮助,我们将不胜感激。
此外,是否有更简单的方法将 CSV 转换为正确的 JSON 格式?
var pre_data = d3.csv.parse(d3.select("pre#data").text());
//document.getElementsByTagName("BODY")[0].innerHTML = data;
var margin = {
top: 20,
right: 120,
bottom: 20,
left: 120
},
width = 1000 - margin.right - margin.left,
height = 500 - margin.top - margin.bottom;
var canvas = d3.select("body").append("svg")
.attr("width", 2000)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function (d) {
return [d.y, d.x];
});
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
//var nested_data = _.nest(csv_data, "Machine");
//var nodes = tree.nodes(nested_data);
var flare_data = {};
var nested_data = d3.nest()
.key(function (d) {
return d['Machine'];
})
.key(function (d) {
return d['Name'];
})
.entries(pre_data);
flare_data.key = "Flare";
flare_data.values = nested_data;
flare_data = reSortFlare(flare_data);
var nodes = tree.nodes(flare_data);
var link = canvas.selectAll(".link")
.data(tree.links(nodes))
.enter().append("path")
.attr("class", "link")
.attr("d", diagonal);
var node = canvas.selectAll(".node")
.data(nodes)
.enter()
.append("g")
.attr("class", "node")
.attr("transform", function (d) {
return "translate(" + d.y + "," + d.x + ")";
});
node.append("circle")
.attr("r", 7)
.on("mouseover", function (d) {
div.transition()
.duration(200)
.style("opacity", .9);
div.html(
"Name: " + (d.name?d.name:d["URL Template"]+(d.xPath.replace("//","/"))) + "<br/>" +
"URL Template: " + d['URL Template'] + "<br/>" +
"Page Start: " + d['Page Start'] + "<br/>" +
"Page Size: " + d['Page Size'] + "<br/>" +
"Max Pages: " + d['Max Pages'] + "<br/>" +
"xPath: " + d['xPath'] + "<br/>" +
"RegEx: " + d['RegEx'] + "<br/>" +
"eCommerce: " + d['eCommerce'] + "<br/>" +
"Search Interval: " + d['Search Interval'] + "<br/>" +
"Additional Variable: " + d['Additional Variable'] + "<br/>" +
"Variable Value: " + d['Variable Value'] + "<br/>")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("click", function (d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
node.append("text")
.attr("dx", function (d) {
return d.children ? -15 : 15;
})
.attr("dy", 3)
.style("text-anchor", function (d) {
return d.children ? "end" : "start";
})
.text(function (d) {
//return d.children ? d.name : d['Name'];
return d.children ? d.name : d["URL Template"]+(d.xPath.replace("//","/"));
});
function reSortFlare(d) {
//console.log("Calling");
for (var key in d) {
if (key == "key") {
d.name = d.key;
delete d.key;
}
if (key == "values") {
d.children = [];
for (var item in d.values) {
d.children.push(reSortFlare(d.values[item]));
}
delete d.values;
}
}
return d;
}
.node circle {
fill: #fff;
stroke: #4B9FC3;
stroke-width: 3px;
}
.node {
font: 12px sans-serif;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 2x;
}
div.tooltip {
position: absolute;
text-align: left;
width: 500px;
height: 200px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
pre {
display:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<body>
<pre id="data">Machine,Name,URL Template,Page Start,Page Size,Max Pages,xPath,RegEx,eCommerce,Search Interval,Additional Variable,Variable Value
"Machine [1]","eSearch - Web-GB","http://example.com/status","1","1","10","//somethingness","([0-9]{1,20})","1","0","Thum","true"
"Machine [1]","eSearch - Web-GB","http://forexample.com/randomness","1","1","10","//nothingness","([0-9]{1,20})","1","0","Kapool","true"
"Machine [1]","Web: Web-US","http://mangasite.com/mangacomic","1","1","10","//itemId","([0-9]{1,20})","1","0","Crawl Natural URL","true"
"Machine [1]","Web: Web-US","http://someothersite.fr/kapala","1","1","10","//itemId","([0-9]{1,20})","1","0","Block Sellers","true"
"Machine [1]","Link Test","http://kistergans.com/papals","0","1","1","//a/@href","(.*)","0","0",,
"Machine [1]","TW Search","https://mankini.jp/ofcourse","0","100","1","//a/@href","(.*/status/.*)","0","0",,
"Machine [1]","TW API","http://storagewars.com","0","1","1","//a/@href","(http.*)","0","0",,
"Machine [1]","Amiz Metaquery","http://www.Amiz.com/s/","1","10","1","//a[contains]/@href","(http://www\.Amiz\.com/","0","0",,
"Machine [1]","Amiz Metaquery Too","http://www.Amiz.de/s/?field-keywords=%q&page=%i","1","1","10","//div/@href","http://www.Amiz.de/).*","0","0",,
"Machine [2]","Subs.com","https://www.subs.com/search?f=%q&p=%i","0","1","10","//dt/a/@href","((https?://[^/]+)?/[^/\+]{10,500})","0","0",,
"Machine [2]","Extra.cc","http://extra.cc/search/","1","1","10","//a/@href","([^#]+)","0","0",,
"Machine [2]","Monitoring","http://monitoring.com/nothing","1","1","1","//nothing","(.*)","0","0",,
"Machine [2]","SM - abe.com - users","http://s.weibo.com/user/lamborghini","1","1","1","//div[@class=""person_detail""]/p[@class=""person_addr""]/a/@href","(.*)","0","0",,
"Machine [2]","SM - koko.com","http://i.youku.com/u_search/?page=%i&q=%q","1","1","10","//li[@class=""u_title""]/a/@href","(http://i.youku.com/u/.+)","0","0",,
"Machine [2]","Amiz.com Page","http://www.Amiz.com/s/?field-keywords=%q&page=%i","1","1","5","//div[@id=""rightResultsATF""]//@href","/dp/([^/]+)/.*","1","0",,
"Machine [3]","MA: Apple.com (iTunes)","http://software.com/aabc","0","200","1","//iTunesApp/trackViewUrl","(@keli)","1","0",,
"Machine [3]","MA: Wipple.com","http://kalamaza.ck/keywords","0","48","5","//a/@href","(http://abc.ck)","0","0",,
"Machine [3]","SM: Linkage.com ","http://stormborn.com/lalala","0","100","5","//a/@href","(lililo+)","0","0",,
"Machine [3]","SM: Afro.com - via SearchTool","http://lipidi.li/lili","0","1","1","//a/@href","(.*/status/[0-9]+)","0","0",,
"Machine [3]","SM: Afro.com","http://sazdarma.ka/yoyo","0","1","1","//a/@href","(.*/status/[0-9]+)","0","0",,</pre>
</body>
我想你正在寻找这个,如果没有请向我询问更多...
首先,您不需要 reSortFlare
函数。这可以通过更改 children accessor function.
var tree = d3.layout.tree()
.size([height, width])
.children(function(d){
return d.values;
});
其次,我相信你可以用.rollup
做你想做的事:
var nested_data = d3.nest()
.key(function(d) {
return d['Machine'];
})
.key(function(d) {
return d['Name'];
})
.rollup(function(d){
var children = [];
d.forEach(function(dSub){
for (var k in dSub){
if (k == 'URL Template' || k == 'xPath')
children.push({'key': dSub[k]})
}
})
return children;
})
.entries(data);
这会产生(示例 code here):