我正在学习d3的画笔概念,想知道是否可以在矩形序列而不是x轴上使用画笔。我创建了12个矩形,并希望使用鼠标在矩形上伸展。
我的代码是:
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;" )
}
//});
}
我的timerdata是:
[
{ "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"}
]
如何使用画笔在矩形上拉伸。我看了一些样品,发现刷子与x轴有关。是不是可以在这些矩形上使用画笔?
答案 0 :(得分:3)
您应该可以使用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
中。请注意,此实现不是特别有效,因为它遍历所有矩形。这在你的情况下不是问题,因为你只有几个,但如果你想在二维中使用更多的矩形,我建议使用更有效的数据结构,例如四叉树。