Fluidlog
Fluidlog

Reputation: 61

Make contenteditable labels in a d3js force layout with foreignObject and drag on Chrome

Here you can find a graph with editable labels (using SVG foreinobject).

nodes.append("foreignObject")
        .attr({width: 100, height: 100})
        .append("xhtml:body")
        .append("xhtml:span")
        .attr("contenteditable", true)
        .html(function(d) { return d.name })
        .on("keyup", function(d, i)
                {
                    console.log(d3.select(this).text());
                });

http://jsfiddle.net/J9HZ2/

If I remove the drag force, it's ok on Chrome & FF.

The problem is that it doesn't work fine on Chrome. OK on firefox. An idea ?

Thanks

Yannick

Upvotes: 6

Views: 1043

Answers (2)

Jamal
Jamal

Reputation: 11

Similar to the original author of this solution I was confused by the d3.event.stopPropagation() solution which I found elsewhere in StackOverflow questions. Basically, you have to stopPropagation of the "mousedown" event, preventing the zoom drag or any other event from ever triggering.

const zoom = d3.zoom().on("zoom", () => {
    console.log("zoomed");
});

d3.select("svg").call(zoom);

d3.select("svg")
    .selectAll("circle")
    .on("mousedown", () => {
        // Without this, clicking the circle will never trigger a mouseup, because zoom will handle mouseup
        d3.event.stopPropagation();
        console.log("mousedown");
    })
    .on("mouseup", () => {
        d3.event.stopPropagation();
        console.log("mouseup");
    });

original answer

Upvotes: 1

ivor
ivor

Reputation: 136

Using Chrome v54, it feels like a bug (a left mouse click on the text node does not display a prompt for entering text). There is a workaround though:

Right click on the text span element. This applies a blue selection to the text. Once selected, you can just start typing to overwrite the existing text.

When you are done with editing the text, click anywhere outside of the text span.

Upvotes: 0

Related Questions