我正在学习 d3 的画笔概念,想知道是否可以在矩形序列而不是 x 轴上使用画笔。我创建了 12 个矩形,并且想使用鼠标在这些矩形上拉伸(stretch)。
我的代码是:
var margin = {top: 4, right: 50, bottom: 20, left: 50},
width = 960 - margin.left - margin.right,
height = 120 - margin.top - margin.bottom;
var svg = d3.select("body").append("svg").attr("id","svgtimer")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.json("TimerData.json", function(data) {
CreateLegend('#timer',svg,"rectangle",data,'Jan','Dec');
})
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
var brush = d3.svg.brush()
.x(d3.scale.identity().domain([0, width]))
.y(d3.scale.identity().domain([0, height]))
.on("brush", brushed);
svg.append("g").call(brush);
function brushed() {
console.log(brush.extent());
}
function CreateLegend(div,svg,svgid,data,header,trail)
{
console.log(data);
var traillength=0;
var svgelem;
//alert("Non-empty");
//d3.json(filepath, function(data) {
console.log(" the svg id is " +svgid);
jsondata = data;
rectangle= svg.selectAll("rect").data(data).enter().append("rect");
var RectangleAttrb = rectangle
.attr("id", function (d,i) { return svgid + "id" + i ; })
.attr("x", function (d) { return d.x_axis; })
.attr("y", function (d) { return d.y_axis; })
.attr("width",function(d) { return d.width; } )
.attr("height",function(d) { return d.height; })
.style("stroke", function (d) { return d.border;})
.style("fill", function(d) { return d.color; });
var textparam = svg.selectAll("text").data(data).enter().append("text");
var yearheader = d3.select("#header");
if(yearheader.empty())
{
var textheader = svg.append("text").attr("dx",20).attr("dy",5).text(header).attr("id",header).attr("style","margin-bottom:21px;border-bottom: solid 2px #ffd97f; font-size:12px;")
}
if (trail.length == 0)
{
//console.log(textheader);
d3.select(header).attr("style","font-size:15.1px;text-decoration:underline");
//svg.attr("style","text-decoration:underline");
}
var text = textparam .attr("x", function (d) { traillength = d.x_axis + d.width +10; return d.x_axis + d.width +10; })
.attr("y", function (d) { return d.y_axis + d.height-5; })
.attr("width",30 )
.attr("height",20)
.attr("style", "text-decoration:none")
.text(function(d) { return d.text; });
var yearheader = d3.select("#trail");
if (trail.length > 0 && yearheader.empty() )
{
svg.append("text").attr("id","trail").attr("dx",traillength-10).attr("dy",5).text(trail).attr("style","margin-bottom:21px;border-bottom: solid 2px #ffd97f; font-size:12px;" )
}
//});
}
我的计时器数据是:
[
{ "x_axis":40, "y_axis": 10,"width":20,"height":15,"color" : "#ffffff","border":"#000000"},
{ "x_axis":60, "y_axis": 10,"width":20,"height":15,"color" : "#ffffff","border":"#000000"},
{ "x_axis":80, "y_axis": 10,"width":20,"height":15,"color" : "#ffffff","border":"#000000"},
{ "x_axis":100, "y_axis":10,"width":20,"height":15,"color" : "#ffffff","border":"#000000"},
{ "x_axis":120, "y_axis":10,"width":20,"height":15,"color" : "#ffffff","border":"#000000"},
{ "x_axis":140, "y_axis":10,"width":20,"height":15,"color": "#ffffff","border":"#000000"},
{ "x_axis":160, "y_axis":10,"width":20,"height":15,"color" : "#ffffff","border":"#000000"},
{ "x_axis":180, "y_axis":10,"width":20,"height":15,"color": "#ffffff","border":"#000000"},
{ "x_axis":200, "y_axis":10,"width":20,"height":15,"color" : "#ffffff","border":"#000000"},
{ "x_axis":220, "y_axis":10,"width":20,"height":15,"color" : "#ffffff","border":"#000000"},
{ "x_axis":240, "y_axis":10,"width":20,"height":15,"color" : "#ffffff","border":"#000000"},
{ "x_axis":260, "y_axis":10,"width":20,"height":15,"color" : "#ffffff","border":"#000000"}
]
如何使用画笔在矩形上拉伸(stretch)。我查看了一些示例,发现画笔与 x 轴相关。难道不能在这些矩形上使用画笔吗?
最佳答案
您应该能够使用d3.svg.brush()
而无需任何特殊修改。我已经获取了你的代码并实现了它 here 。初始化并附加画笔的代码如下。
var brush = d3.svg.brush()
.x(d3.scale.identity().domain([0, width]))
.y(d3.scale.identity().domain([0, height]))
.on("brush", brushed);
svg.append("g").call(brush);
这将初始化画笔并将身份比例分配给 x
和 y
维度。在您的代码中,您实际上并没有使用比例将用户转换为屏幕坐标,而是直接获取用户坐标。这就是身份量表的作用。每个域都设置为图形各自的维度,以告诉画笔可以画多大的区域。
您可以使用 .extent()
function 指定画笔的初始范围。 。在您的情况下,处理程序的实现如下所示。
function brushed() {
var e = brush.extent(),
selected = svg.selectAll("rect").filter(function(d) {
return d.x_axis <= e[1][0] && d.x_axis + d.width >= e[0][0] && d.y_axis <= e[1][1] && d.y_axis + d.height >= e[0][1];
})
console.log(selected);
}
它首先获取画笔的当前范围,然后用它过滤绘制的矩形。也就是说,对于每个矩形,代码检查它是否与画笔矩形重叠。如果是,则将其保留在selected
列表中。请注意,此实现并不是特别有效,因为它会迭代所有矩形。对于您的情况来说,这不是问题,因为您只有几个,但如果您想将其与更多二维矩形一起使用,我建议使用更有效的数据结构,例如四叉树。
关于d3.js - 在一系列矩形上使用画笔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21108915/