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对象,或者创建我自己的Circle
对象,该对象具有pointAt
函数,并包装d3对象。这两个都是个好主意吗?
在其他方面,我觉得我想要类似的东西——有点像我想将"对象"映射到文档,而不是将简单的旧数据映射到文档。这是一个常见的需求,还是我在概念上遗漏了一些东西?
处理上述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
根据svg的集合属性(current_attr
,current_style
)在svg上绘制一个圆。要在svg上画一个圆圈,可以用d3.js的方式:
var new_circle = innerCircle();
svg.call( new_circle );
_circle
函数有3个定义的方法,attr
、style
和pointAt
。attr
和style
是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);
这种编程风格的最后一个警告是在所有setter函数末尾的return _circle;
语句,它允许链接。因此,您的示例可以通过以下方式复制:
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>
- 为什么在单独的函数中应用时转换会闪烁/断断续续(D3)
- d3中堆栈函数和嵌套函数之间的差异
- D3数学函数创建
- D3选择html——传递函数时,索引从1开始,而不是从0开始
- 将for循环的值赋给函数d3
- 基本 D3.js:如何在函数中使用联接
- D3:使用 nest 函数将带有父键的平面数据转换为层次结构
- 检查D3.js中的函数中是否存在URL
- 如何动态地决定并告诉d3.json()函数何时使用哪个json
- D3未捕获类型错误:path.data不是函数
- d3.event在反跳函数内部为null
- D3中的可重用函数
- d3通过改变参数化函数使折线图水平动画化
- 链接D3.js力布局网络的阈值函数中的笔划宽度
- d3-append()带有函数参数
- 将JSON从rails控制器加载到javascript文件中的d3.dedefe()函数
- d3.js voronoi.clipExtent()返回错误:undefined不是函数
- D3 折线图:x 折线函数始终呈现 NaN
- 刷新函数未正确调用 d3
- 如何让一个事件调用多个函数?D3/Javascript