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

标签 d3.js brush

我正在学习 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);

这将初始化画笔并将身份比例分配给 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列表中。请注意,此实现并不是特别有效,因为它会迭代所有矩形。对于您的情况来说,这不是问题,因为您只有几个,但如果您想将其与更多二维矩形一起使用,我建议使用更有效的数据结构,例如四叉树。

关于d3.js - 在一系列矩形上使用画笔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21108915/

相关文章:

javascript - 如何在 d3.js 的多焦点强制布局中动态更新焦点

javascript - .data(...) 字段的 D3js 值在窗口大小调整时不会更改。有办法改变吗?

javascript - 正确填充 D3 创建的增强 svg 路径

delphi - 对角画笔样式给我黑色区域

javascript - 箱线图中的画笔选择(d3.js)

javascript - 为什么图形线偏离 Y 轴和 X 轴?

javascript - d3 : How to get stacked graph to zoom?

d3.js - 如何控制d3.brush(右击)

wpf - 有没有办法让 DynamicResource 对于 ResourceDictionary 中的 Freezable 是动态的?

javascript - HTML5 Canvas javascript 涂抹画笔工具