首先,我正在使用d3.js和SVG。我已经得到了这条代码的路径:
var one = d3.select('#canvas1');
var oneCanvas = one.append("svg").attr("width", 200).attr("height", 190);
oneCanvas.append("svg:path")
.attr("d", "M100 15 A 55 55, 0, 0, 0, 73 61 A 55 55, 0, 0, 1, 127 61 A 64 64, 0, 0, 0, 100 15")
.style("stroke","black")
.style("fill", "white")
.style("stroke-width", 1)
.on("click", function(){
d3.select(this).style("fill", "magenta");
alert("You've clicked on the path in the 1st div");
});
我整个路径大约使用了20次。通过这种方法,我将重复上述代码,如https://jsfiddle.net/s26kghmq/
所示我不使用'd3.selectAll'
的原因是,通过这样做,我将无法在单击路径时设置不同的功能。
我实施了svg的'def'
和'use'
,但这对我没有帮助,因为如果我之前设置了一个样式,我无法在'use'
中再次覆盖它如下所述:http://taye.me/blog/svg/a-guide-to-svg-use-elements/
我想知道是否有一种替代方法来实现功能而不重复?
提前感谢您的所有答案。
答案 0 :(得分:2)
您可以将路径绘图放在单独的函数中
var drawPath = function(ele, clickFunction){
ele.append("svg:path")
.attr("d", "M100 15 A 55 55, 0, 0, 0, 73 61 A 55 55, 0, 0, 1, 127 61 A 64 64, 0, 0, 0, 100 15")
.style("stroke","black")
.style("fill", "white")
.style("stroke-width", 1)
.on("click", clickFunction)
}
然后重复使用这个函数:
oneCanvas.call(drawPath, yourSpecificClickFunction)
答案 1 :(得分:2)
如果.on
事件中的回调不同并不重要,有很多方法可以解决这个问题。 d3
完全是关于数据绑定,迭代和不重复代码。所以,你真的应该使用selectAll
。
var data = [1,2];
var color = d3.scale.ordinal()
.domain(data)
.range(['magenta','yellow']);
var one = d3.selectAll('.v1')
.data(data)
.append("svg")
.attr("width", 200)
.attr("height", 190)
.append("svg:path")
.attr("d", "M100 15 A 55 55, 0, 0, 0, 73 61 A 55 55, 0, 0, 1, 127 61 A 64 64, 0, 0, 0, 100 15")
.style("stroke","black")
.style("fill", "white")
.style("stroke-width", 1)
.on('click', function(d){
d3.select(this).style("fill", color(d));
alert("You've clicked on the path in the " + d + " div");
});
.v1{
width: 200px;
height: 100px;
background: white;
border: 1.5px solid #000000;
}
#canvas2{
position: absolute;
top: 150px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="canvas1" class="v1"></div>
<div id="canvas2" class="v1"></div>
评论更新
如果回调是唯一的每个数据,那么它们也只是成为数据的属性。此外,您始终可以分割出共享和特定功能:
function sharedFunc(elem,d){
d3.event.stopPropagation();
d3.select(elem).style('fill', d.color);
}
var data = [
{
specificFunc: function(d){
alert("you've clicked the 1st one");
},
color: 'magenta'
},{
specificFunc: function(d){
alert("you've clicked the 2nd one");
},
color: 'yellow'
}
];
d3.selectAll('.v1')
.data(data)
.append("svg")
.attr("width", 200)
.attr("height", 190)
.append("svg:path")
.attr("d", "M100 15 A 55 55, 0, 0, 0, 73 61 A 55 55, 0, 0, 1, 127 61 A 64 64, 0, 0, 0, 100 15")
.style("stroke","black")
.style("fill", "white")
.style("stroke-width", 1)
.on('click', function(d){
sharedFunc(this, d);
d.specificFunc(d);
});
$("#canvas1").click(function(){
alert("you clicked on the canvas");
});
.v1{
width: 200px;
height: 100px;
background: white;
border: 1.5px solid #000000;
}
.v2{
width: 200px;
height: 100px;
background: white;
border: 1.5px solid #000000;
}
#canvas2{
position: absolute;
top: 150px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="canvas1" class="v1"></div>
<div id="canvas2" class="v1"></div>