d3.js - 在一系列矩形上使用画笔

时间:2014-01-14 08:31:01

标签: d3.js brush

我正在学习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轴有关。是不是可以在这些矩形上使用画笔?

1 个答案:

答案 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);

这会初始化画笔并为xy维度指定标识比例。在您的代码中,您实际上并没有使用比例将用户转换为屏幕坐标,而是直接使用用户坐标。这就是身份尺度的作用。每个域的域都设置为图形的相应尺寸,以告诉刷子刷面积有多大。

您可以使用.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中。请注意,此实现不是特别有效,因为它遍历所有矩形。这在你的情况下不是问题,因为你只有几个,但如果你想在二维中使用更多的矩形,我建议使用更有效的数据结构,例如四叉树。