gal007
gal007

Reputation: 7192

How to enable text selection in a D3.js-SVG that has zoom enabled?

I'm new with D3 and I going crazy with this detail: I'm building a graph which is a Bubble graph with some labels inside, and I would like to enable users to be able to select the textual labels of the bubbles. I mean, in the traditional way, as if they are highlighting any other text in a webpage.

By default, the graph allows users to select the text in the bubbles, but if I enable the zoom, I can no longer select the texts. I enabled the zoom by:

var svg = d3
      .select(this.domSelector)
      .append("svg")
      .attr("width", width)
      .attr("height", height)
      .attr("class", "bubble")
      .call(d3.behavior.zoom().on("zoom", function () {
            svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")")
      }))

I tried to temporally disable this effect by preventing it if the user is clicking any element byt the background. This is to say:

.call(d3.behavior.zoom().on("zoom", (evt) => {
     if(d3.event.sourceEvent.target.tagName.toLocaleLowerCase() == "svg"){
         svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
     }
     else svg.on('.zoom', null); }))

But the behaviour is the same: I can not select the text. Any idea?

https://jsfiddle.net/gal007/e2gsvkLt/

Upvotes: 2

Views: 528

Answers (1)

Flash Thunder
Flash Thunder

Reputation: 12036

You can assign mousedown event to the text element with d3.event.stopPropagation(). Would be something like that:

  generateBubbleNames(nodes){
    var maxCharacters = 10;
    var labels = nodes.selectAll("text.label")
    .data(function(d) { return [d]; });

    labels.enter().append("text")
      .attr({
      "class": "label",
      dy: "0.35em"
    })
    .style("text-anchor", "middle")
    .style("font-size", function(d) { return d.r / 3; })
    .text(function(d) {
      return d[0]
    })
    .on("mousedown", function(){
      d3.event.stopPropagation();
    })
  }

Here's a working example:

JsFiddle

Upvotes: 3

Related Questions