写这个的替代方法?

时间:2016-03-12 16:06:39

标签: javascript jquery d3.js svg

首先,我正在使用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/

我想知道是否有一种替代方法来实现功能而不重复?

提前感谢您的所有答案。

2 个答案:

答案 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>

相关问题