繁体   English   中英

D3中的可重用功能

[英]Reusable functions in D3

我是d3的新手,并且是相当普通的javascript程序员。 我有一些代码可以创建一个圆,还有一个函数可以获取圆上某个点的x和y坐标:

var innerCircle = svg.append('circle')
  .attr({
    cx: 100,
    cy: 100,
    r: 50,
    'stroke': 'white',
    'fill': 'transparent',
  });

var pointOnCircle = function(circle, radians){
  var cx = parseInt(circle.attr('cx'));
  var cy = parseInt(circle.attr('cy'));
  var r = parseInt(circle.attr('r'));
  var x = cx + Math.sin(radians) * r;
  var y = cy + Math.cos(radians) * r;
  return {x: x, y: y};
}

有用。 但是我觉得继续使用这种方法会使我的代码成为混乱的全局函数包,而且我应该能够使其面向对象,因此不必调用:

var point = pointOnCircle(circle, Math.PI);

我可以打电话给:

var point = circle.pointAt(Math.PI);

但这会涉及到我要么以某种方式将pointAt函数附加到d3对象,要么创建我自己的具有pointAt函数的Circle对象并包装d3对象。 这些都是好主意吗?

在其他方面,我觉得我想要类似的东西-有点像我想将“对象”映射到文档,而不是将普通的旧数据映射到文档。 这是一个普遍的要求,还是我在概念上缺少一些东西?

解决pointOnCircle遇到的pointOnCircle问题的最佳方法是什么?

d3的大多数示例都是小型的,独立的并且用一个脚本编写。 是否有任何示例说明如何构建具有更多可重用功能的产品?

您可以遵循d3.js样式的函数式编程,如下所示

function innerCircle() {
    var current_attr, current_style, circle_elem;

    var _circle = function (svg) {
        circle_elem = svg.append('circle')
            .attr(current_attr)
            .attr(current_style);

        return circle_elem;
    }

    _circle.pointAt = function (randians) {
        if(! circle_elem)       //If the circle is not drawn yet.
            return {x: -1, y: -1};

      var cx = parseInt(circle_elem.attr('cx'));
      var cy = parseInt(circle_elem.attr('cy'));
      var r = parseInt(circle_elem.attr('r'));
      var x = cx + Math.sin(radians) * r;
      var y = cy + Math.cos(radians) * r;
      return {x: x, y: y};
    }

    _circle.attr = function(attr_val){
        if(! arguments.length)
            return current_attr;

        current_attr = attr_val;
        return _circle;
    }

    _circle.style = function(style_val){
        if(arguments.length == 1)
            return current_style;

        current_style = style_val;
        return _circle;
    }

    return _circle;
}

这是函数式编程的典型示例。 主要对象是_circle函数,是通过调用innerCircle获得的。 _circle根据其设置的属性( current_attrcurrent_style )向svg 绘制一个圆。 要在svg上画一个圆,可以使用d3.js方式:

var new_circle = innerCircle();
svg.call( new_circle );

_circle函数具有3个定义的方法, attrstylepointAt attrstyle是getter / setter函数,如果不带参数调用它们,则它们将返回当前值(getter);如果带参数调用它们,则将为其设置当前值。

new_circle.style(); //get the current style

//set attributes
new_circle.attr({
    cx: 100,
    cy: 100,
    r: 50,
    'stroke': 'white',
    'fill': 'transparent',
});

您也可以类似地调用pointAt函数。

new_circle.pointAt(Math.PI);

这种编程风格的最后一个警告是return _circle; 所有setter函数末尾的语句,允许链接。 因此,您的示例可以通过以下方式重现:

var new_circle = innerCircle()
  .attr({
    cx: 100,
    cy: 100,
    r: 50,    
  })
  .style({
    'stroke': 'white',
    'fill': 'transparent',
  });

svg.call(new_circle);

希望这可以帮助。 让我知道任何不清楚的地方。

我希望这有帮助。

 var myProgram = {}; myProgram.circleModule = (function() { var innerCircle = d3.select("#svg").append('circle') .attr({ cx: 100, cy: 100, r: 50, 'stroke': 'black', 'fill': 'red', }); var pointOnCircle = function(circle, radians) { var cx = parseInt(circle.attr('cx')); var cy = parseInt(circle.attr('cy')); var r = parseInt(circle.attr('r')); var x = cx + Math.sin(radians) * r; var y = cy + Math.cos(radians) * r; return { x: x, y: y }; } return { circle: innerCircle, pointOnCircle: pointOnCircle } })(); 
 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Untitled Document</title> <script src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> </head> <body> <svg id="svg" width="200" height="200"> </svg> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM