Q:

d3.js in vue component - How to hook mouse events to elements?

I have a working code in plain javascript for an interactive D3.js map and now trying to create a vue.js component out of it. I have defined all functions as methods and I don't get any warning or fault message but none of the mouse events are hooked. I've tried both, the D3.js way (.on("click", this.clickBG)) as well as the vue (.attr("v-on:click","clickBG")) without success.

    // vorlage: https://dev.to/ignoreintuition/binding-data-to-charts-using-vue-components-and-d3-4i27
    import * as d3 from 'd3';
    
    export default {
        props: ['data','vegbed'], 
        data: function () {
            return {
                gardenbox: {}
            }
        },
        computed: {
            displaywidth: function() { return 600; },
            displayheight: function() { return this.displaywidth*(this.vegbed.length/this.vegbed.width); },
            margin: function() { return {top: 0, right: 0, bottom: 0, left: 0}; }
        },
        methods: {
            initalizeChart: function () {
                this.drawGardenBox();
            },

            virtDia: function (realDia) {
                return (this.displaywidth/this.vegbed.width)*realDia;
            },
            
            clickPlant: function() {
                d3.selectAll(".selected").raise().classed("selected",false);
                d3.select(_this).selectAll(".plant").raise().classed("selected", true);
                d3.selectAll("#"+this.id).classed("selected", true);      
            },
            clickBG: function() {
                console.log("click");
                d3.selectAll(".selected").raise().classed("selected",false);
            },
            
            draggedPlant: function(d) {
                d3.select(this).attr("transform","translate("+(d.x = d3.event.x)+","+(d.y = d3.event.y)+")");
            },
            
            dragStartedPlant: function() {
                d3.selectAll(".selected").raise().classed("selected",false);
                d3.select(this).selectAll(".plant").raise().classed("selected", true);
                d3.selectAll("#"+this.id).classed("selected", true);

                //d3.event.sourceEvent.stopPropagation();
            },    
            dragEndedPlant: function(d) {
                
            },
            refreshBed: function () {
                let _this = this; // Workaround to call functions from inside callbacks
                var gplant = this.gardenbox.selectAll("g")
                    .data(this.data).enter().append("g")
                    .attr("id", function(d){ return d.id; })
                    .attr("transform", function(d){ return "translate("+d.x+","+d.y+")";  })
                    .on("click", this.clickPlant)
                    //.attr("v-on:click","this.clickPlant")
                    .call(d3.drag()
                    .on("start", this.draggedPlant)
                    .on("drag", this.dragStartedPlant)
                    .on("end", this.dragEndedPlant));

                gplant.append("circle") // max size
                    .attr('class', 'plant')
                    .attr("cx", function(d) { return d.x; })
                    .attr("cy", function(d) { return d.y; })
                    .attr("r", function(d) { return _this.virtDia(d.plant.adult_diameter); });

                gplant.append("circle") // min size
                    .attr('class', 'plant')
                    .attr("cx", function(d) { return d.x; })
                    .attr("cy", function(d) { return d.y; })
                    .attr("r", function(d) { return _this.virtDia(d.plant.exposure_diameter); });

                gplant.append("image")
                    .attr('class', 'plant')
                    .attr("xlink:href", function(d) { return d.picref; })
                    .attr("x", function(d) { return d.x-(d.picsize/2); })
                    .attr("y", function(d) { return d.y-(d.picsize/2); })
                    .attr("width", function(d) { return d.picsize; })
                    .attr("height", function(d) { return d.picsize; });
            },
            
            drawGardenBox: function () {
                this.gardenbox = d3.select('#vegbedcontainer').append('svg')
                        .attr("width", this.displaywidth + this.margin.left + this.margin.right)
                        .attr("height", this.displayheight + this.margin.top + this.margin.bottom)
                // hintergrund für deselect zeichen
                var bg = this.gardenbox.append("g")
                        //.attr("v-on:click","clickBG");
                        .on("click", this.clickBG); // unselect on background click

                bg.append("rect") 
                    .attr('class', 'bg')
                    .attr("x", this.margin.left)
                    .attr("y", this.margin.top)
                    .attr("width", this.displaywidth + this.margin.left + this.margin.right)
                    .attr("height", this.displayheight + this.margin.top + this.margin.bottom)
            }
        },


        // lifecycle events
        mounted: function () { // <-- lifecycle events
            console.log('VegBedEditor mounted.')
            this.initalizeChart();
            this.refreshBed();
        },
        // watch functions
        watch: { // <-- watch functions
            'data': {
                handler: function (val) {
                    this.refreshBed();
                },
                deep: true
            }
        },
        template: `<div id="vegbedcontainer"><!-- SVG goes here --></div>`
    }

A:

Here is the result of some experimenting that works in my Vue app.
Setting click handler on svg background
drawGardenBox: function () {
  this.gardenbox = d3.select('#vegbedcontainer').append('svg')
    .attr("width", this.displaywidth + this.margin.left + this.margin.right)
    .attr("height", this.displayheight + this.margin.top + this.margin.bottom)

  var bg = d3.select('svg')
    .on("click", this.clickBG); // unselect on background click

Stopping click propagation from other handler
clickPlant: function() {
  d3.selectAll(".selected").raise().classed("selected",false);
  d3.select(_this).selectAll(".plant").raise().classed("selected", true);
  d3.selectAll("#"+this.id).classed("selected", true); 
  d3.event.stopPropagation(); 
},

Setting d3.event
I import just selected parts of the d3 library, including event, but initially d3.event.stopPropagation() was failing because d3.event was null.
Thanks to this question importing d3.event into a custom build using rollup, I changed the event import and it now works
import { select, selectAll, event, customEvent } from 'd3-selection'
import { zoom } from 'd3-zoom'
import { tree, hierarchy } from 'd3-hierarchy'

export const d3 = {
  select,
  selectAll,
  tree,
  hierarchy,
  zoom,
  // event,
  get event() { return event; },
  customEvent
}

