Custom context menu in d3 and svg

I would like to have custom context menu appearing when I right click on an svg circle.
For now I have found this answer that helps me to handle the right click with the following code:

.on("contextmenu", function(data, index) {
   //handle right click

   //stop showing browser menu
   d3.event.preventDefault()
});

Now I would like to know how I can show a box containing some HTML.

  • popup window at chrome extensions' context menu
  • Webkit: contextmenu / click handling bug workaround?
  • HTML5 contextmenu - Access originally clicked element when menu item is clicked
  • Is it possible to use a variable as a function name
  • Adding keyboard shortcut to context menu for Google Chrome extensions?
  • Right mouse click detection on SVG shape in JavaScript not working
  • Thanks in advance.

  • jQuery event contextmenu triggers underlaying div
  • Prevent default context menu in kinetic JS stage rightclick?
  • Any way to disable tooltip (title attribute) when right click (contextmenu)?
  • Multiple context menu entries for a chrome extension?
  • 2 jQuery.contextMenu on a page with different trigger
  • jQuery context menu get clicked item
  • 2 Solutions collect form web for “Custom context menu in d3 and svg”

    d3.select('#stock_details .sym').on("contextmenu", function(data, index) {
        var position = d3.mouse(this);
        d3.select('#my_custom_menu')
          .style('position', 'absolute')
          .style('left', position[0] + "px")
          .style('top', position[1] + "px")
          .style('display', 'block');
    
        d3.event.preventDefault();
    });
    

    Just a comment on the accepted answer (don’t have enough points to comment directly). But it seems like the newest version of d3 requires d3.event.pageX and d3.event.pageY instead of just x and y. Per the documentation here.

    So my code is (with some IE help from this site):

    .on('contextmenu', function(data, index) {
          if (d3.event.pageX || d3.event.pageY) {
              var x = d3.event.pageX;
              var y = d3.event.pageY;
          } else if (d3.event.clientX || d3.event.clientY) {
              var x = d3.event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
              var y = d3.event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
          }
    
          d3.select('#action_div')
            .style('position', 'absolute')
            .style('left', x + 'px')
            .style('top', y + 'px')
            .style('display', 'block');
    
          d3.event.preventDefault();
      })