使用D3.js在CSV中复制行
这里是我的问题:我有一个CSV文件,其中包含以下列 项目类型汽车、摩托车、公共汽车等,。。。 物主 城市/州 具体车主拥有多少辆汽车/摩托车/公共汽车 我想制作一个动态气泡D3.js图表。每个气泡应该代表一个项目,我希望用户可以按类型、所有者或状态对其进行排序。我需要一个运行良好的脚本,只是它需要CSV中的每一行来生成一个气泡。我试图找到一种方法来复制数字<1时的气泡,但直到现在我还没有找到 你有什么建议?我应该使用D3.js来完成吗?jQuery?其他的 代码如下:使用D3.js在CSV中复制行,csv,d3.js,Csv,D3.js,这里是我的问题:我有一个CSV文件,其中包含以下列 项目类型汽车、摩托车、公共汽车等,。。。 物主 城市/州 具体车主拥有多少辆汽车/摩托车/公共汽车 我想制作一个动态气泡D3.js图表。每个气泡应该代表一个项目,我希望用户可以按类型、所有者或状态对其进行排序。我需要一个运行良好的脚本,只是它需要CSV中的每一行来生成一个气泡。我试图找到一种方法来复制数字
你试过复制CSV中的行吗?是的,我这样做了,效果很好,谢谢!但这个解决方案不是最优的,因为我会定期收到CSV的更新版本,每次上传之前我都要修改它。当然这是可行的,但我更喜欢100%自动化的解决方案。你可以通过编程来做同样的事情——复制行。Yeap。我刚刚写了一个简短的谷歌应用程序脚本来复制行!谢谢你的帮助
d3.csv('data/test.csv', function (error, data) {
var width = 600, height = 600;
var fill = d3.scale.ordinal().range(['#827d92','#827354','#523536','#72856a','#2a3285'])
var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height);
_.each(data, function (elem) {
elem.radius = 5;
elem.x = _.random(0, width);
elem.y = _.random(0, height);
});
var padding = 2;
var maxRadius = d3.max(_.pluck(data, 'radius'));
function getCenters(vname, w, h) {
var nodes = [], c =[], result = {};
var v = _.uniq(_.pluck(data, vname));
var l = d3.layout.treemap().size([w, h]).ratio(1/1);
_.each(v, function (k, i) {
c.push({name: k, value: 1});
});
nodes = l.nodes({children: c})[0].children;
for (var i = 0; i < nodes.length; i++) {
result[nodes[i].name] = nodes[i];
}
return result;
}
var nodes = svg.selectAll("circle")
.data(data);
nodes.enter().append("circle")
.attr("class", "node")
.attr("cx", function (d) { return d.x; })
.attr("cy", function (d) { return d.y; })
.attr("r", 2)
.style("fill", function (d) { return fill(d.cat_int); })
.on("mouseover", function (d) { showPopover.call(this, d); })
.on("mouseout", function (d) { removePopovers(); })
nodes.transition().duration(1000)
.attr("r", function (d) { return d.radius; })
var force = d3.layout.force()
.charge(0)
.gravity(0)
.size([width, height])
draw('cat_int');
$( ".btn" ).click(function() {
draw(this.id);
});
function draw (varname) {
var foci = getCenters(varname, 600, 600);
force.on("tick", tick(foci, varname, .45));
labels(foci)
force.start();
}
function tick (foci, varname, k) {
return function (e) {
data.forEach(function(o, i) {
var f = foci[o[varname]];
o.y += ((f.y + (f.dy / 2)) - o.y) * k * e.alpha;
o.x += ((f.x + (f.dx / 2)) - o.x) * k * e.alpha;
});
nodes
.each(collide(.1))
.attr("cx", function (d) { return d.x; })
.attr("cy", function (d) { return d.y; });
}
}
function labels (foci) {
svg.selectAll(".label").remove();
svg.selectAll(".label")
.data(_.toArray(foci)).enter().append("text")
.attr("class", "label")
.text(function (d) { return d.name })
.attr("transform", function (d) {
return "translate(" + (d.x + (d.dx / 2)) + ", " + (d.y + 20) + ")";
});
}
function removePopovers () {
$('.popover').each(function() {
$(this).remove();
});
}
function showPopover (d) {
$(this).popover({
placement: 'auto top',
container: 'body',
trigger: 'manual',
html : true,
content: function() {
return "Category: " + d.cat_int + "<br/> Owner: " + d.owner + "<br/>Sate: " + d.state; }
});
$(this).popover('show')
}
function collide(alpha) {
var quadtree = d3.geom.quadtree(data);
return function(d) {
var r = d.radius + maxRadius + padding,
nx1 = d.x - r,
nx2 = d.x + r,
ny1 = d.y - r,
ny2 = d.y + r;
quadtree.visit(function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== d)) {
var x = d.x - quad.point.x,
y = d.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = d.radius + quad.point.radius + padding;
if (l < r) {
l = (l - r) / l * alpha;
d.x -= x *= l;
d.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
});
};
}
});