D3设计可重用组件以在“调用”期间接受参数

时间:2019-01-14 19:35:24

标签: javascript d3.js

这个问题在d3 v5上

我正在尝试创建一个接受参数的可重用组件。在构建组件时,我找不到语法的文档/示例,这将有助于call使用参数的组件。

例如使用本机d3画笔,我可以实现以下目标:

var data = [
  {id: 1, mv: [100,500]},
  {id: 2, mv: [300,600]},
  {id: 3, mv: [800,1000]}
];

var brush = d3.brushX()
    .extent([[0, 0], [1500, 90]]);
    
var svg = d3.select("svg");

var g = svg.selectAll("g").data(data).enter()
  .append("g")
  .attr("transform", (d,i)=>"translate(0,"+i*100+")");
  
// able to pass a function parameter to brush.move
g.call(brush)
  .call(brush.move, (d,i)=>d.mv);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width=1500 height=1000></svg>

我的问题是:如何编写我的组件,以便我可以接受与brush.move中接受的参数类似的参数

这是我在搜索中遇到的:

不幸的是,没有一个像上面的brush.move那样处理传递的参数。

我组件的当前语法类似于上面的简单示例。

myorg.myelement = function() {
  // variables that can be set when constructing the function
  var height = "", maxwidth = "";

  function my(selection) {

    selection.each(function(d,i) {

      var elem = d3.select(this);
      // I have `this`, d and i
      // How can I get the param passed?
      ...

我正在寻找组件中的语法以接受在call期间传递的参数

谢谢!

1 个答案:

答案 0 :(得分:1)

好吧,正如@altocumulus所建议的那样,作为公共pen悔,我发表自己的回答:-)

当然,有关如何call函数的文档非常清楚。只需传递其他参数即可:-)

但是在这里,我将更进一步,为一个可重用的函数创建一个蓝图,该函数可以接受函数参数并且也可以使用该函数,因为我没有在网上找到示例。作为Java语言的新手,我在这里学到了一些新东西,包括applyarguments

// Here's my re-usable component

var myown = {};
myown.brush = function(){

  // setup variable
  var height = 0;
  
  function my(group){
    group.each(function(d,i){
      // here is the code for creating brush
      // note `this` is also available (in addition to d and i), for e.g.
      var b = d3.select(this);
      
      console.log("inside my each "+height);
      
    });
  }
  
  my.move = function (group, position){
    console.log("in move function");
    
    group.each(function(d,i){
      // here is the code for moving the brush
      // note `this` is also available (in addition to d and i), for e.g.
      var b = d3.select(this), that = this;
    
      console.log("inside move each");
      console.log(typeof(position));   // note it is function
      
      // now call that function
      // using "apply" and "arguments"
      let pos = position.apply(that, arguments);
      console.log(pos); 
    
    })
    
    return my;
  }
  
  my.height = function(value){
    if(!arguments.length) return value;
    height = +value;
    return my;
  }
  
  return my;
};

// Okay, now use all that nice code

var data = [
  {id: 1, mv: [100,500]},
  {id: 2, mv: [300,600]},
  {id: 3, mv: [800,1000]}
];

var brush = myown.brush().height(90);
    
var svg = d3.select("svg");

var g = svg.selectAll("g").data(data).enter()
  .append("g")
  .attr("transform", (d,i)=>"translate(0,"+i*100+")");
  
g.call(brush).call(brush.move, (d,i)=>d.mv);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width=1500 height=1000></svg>