SachiDangalla SachiDangalla - 1 month ago 26
CSS Question

Add background to svg polyline

I'm trying to add an overlay-like-effect to an svg polyline. The basic goal is to make it easy to click on the line and since the line is too thin, I want to add a background overlay that will lighlight when hovered on.

I tried it with the following approach using a polygon, but that looks tedious. (The line is always comprised of 3 segments)

Is there a much sophisticated way of achieving the goal.

Or is there a better way to make the line more-clickable?



function draw(x1, y1, x2, y2) {

var svg = d3.select("#canvas");

var overlay = svg.append("polygon")
.style("fill", "yellow")
.style("opacity", "0")
.attr("points", function() {
var s = 5,
h = 20;
var p1 = [x1, y1 - s],
p2 = [x1 + h + s, y1 - s],
p3 = [x2 - h + s, y2 - s],
p4 = [x2, y2 - s],
p5 = [x2, y2 + s],
p6 = [x2 - h - s, y2 + s],
p7 = [x1 + h - s, y1 + s],
p8 = [x1, y1 + s];
return p1 + " " + p2 + " " + p3 + " " + p4 + " " + p5 + " " + p6 + " " + p7 + " " + p8;
})
.on("mouseover", function() {
d3.select(this).style("opacity", "0.5");
})
.on("mouseleave", function() {
d3.select(this).style("opacity", "0");
});
var line = svg.append("polyline")
.style("fill", "none")
.style("stroke", "black")
.attr("points", function() {
var margin = 20;
var p1 = [x1, y1],
p2 = [x1 + margin, y1],
p3 = [x2 - margin, y2],
p4 = [x2, y2];

return p1 + " " + p2 + " " + p3 + " " + p4;
});

}
draw(10, 10, 200, 200);

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.js"></script>
<svg height="250" width="500" id="canvas">


</svg>




Answer

Can you not insert another line with an opacity of zero with the events on that one ? Something like so :

function draw(x1, y1, x2, y2) {

  var svg = d3.select("#canvas");

 /* var overlay = svg.append("polygon")
    .style("fill", "yellow")
    .attr("points", function() {
      var s = 5,
        h = 20;
      var p1 = [x1, y1 - s],
        p2 = [x1 + h + s, y1 - s],
        p3 = [x2 - h + s, y2 - s],
        p4 = [x2, y2 - s],
        p5 = [x2, y2 + s],
        p6 = [x2 - h - s, y2 + s],
        p7 = [x1 + h - s, y1 + s],
        p8 = [x1, y1 + s];
      return p1 + " " + p2 + " " + p3 + " " + p4 + " " + p5 + " " + p6 + " " + p7 + " " + p8;
    });
  */
  
  var lineBackround = svg.append("polyline")
    .style("fill", "none")
    .style("stroke", "yellow")
    .style('stroke-width',5)
    .style('opacity', 0)//change this to 0 to not see it
    .attr("points", function() {
      var margin = 20;
      var p1 = [x1, y1],
        p2 = [x1 + margin, y1],
        p3 = [x2 - margin, y2],
        p4 = [x2, y2];

      return p1 + " " + p2 + " " + p3 + " " + p4;
    })
    .on('mouseover', function(){
      d3.select(this).style('opacity',1);
      //alert('over')    
    })
      .on('mouseout', function(){
      d3.select(this).style('opacity',0);
      //alert('over')    
    })
  
  
  var line = svg.append("polyline")
    .style("fill", "none")
    .style("stroke", "black")
    .attr("points", function() {
      var margin = 20;
      var p1 = [x1, y1],
        p2 = [x1 + margin, y1],
        p3 = [x2 - margin, y2],
        p4 = [x2, y2];

      return p1 + " " + p2 + " " + p3 + " " + p4;
    })
 
  
  
    

}
draw(10, 10, 200, 200);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.js"></script>
<svg height="250" width="500" id="canvas">


</svg>