Search code examples
javascriptsvgd3.jsace-editor

Ace editor in SVG Foreign Object


How would one add an Ace Editor to a D3 SVG? Is this possible? What is the best way to go about doing so?

Below is my attempt to to create a foreignObject element and add the editor to it, to no avail:

    var w = window.innerWidth,
      h = window.innerHeight;

    var svg = d3.select('body').append('svg')
      .attr('width', w)
      .attr('height', h);

    var group = svg.append("g");

    var radius = w / 4;

    var circle = group.append("circle")
      .attr("cx", w / 2)
      .attr("cy", h / 2)
      .attr("r", radius)
      .attr("fill", "black");

    group.append('foreignObject')
      .attr("x", w / 2 - radius / 2)
      .attr("y", h / 2 - radius / 2)
      .attr("width", radius)
      .attr("height", radius)
      .style("background-color", "red")
      .append("xhtml:div")
      .attr("id", "editor")
      .attr('width', '50')
      .attr('height', '50');

    var editor = ace.edit("editor");
    editor.setTheme("ace/theme/monokai");
    editor.getSession().setMode("ace/mode/javascript");
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.9/ace.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>


Solution

  • In html width and height are CSS styles, not attributes. Once I fixed that and made it big enough to see, the editor seemed to work for me, at least in Firefox which is where I tested it.

        var w = window.innerWidth,
          h = window.innerHeight;
    
        var svg = d3.select('body').append('svg')
          .attr('width', w)
          .attr('height', h);
    
        var group = svg.append("g");
    
        var radius = w / 4;
    
        var circle = group.append("circle")
          .attr("cx", w / 2)
          .attr("cy", h / 2)
          .attr("r", radius)
          .attr("fill", "black");
    
        group.append('foreignObject')
          .attr("x", w / 2 - radius / 2)
          .attr("y", h / 2 - radius / 2)
          .attr("width", radius)
          .attr("height", radius)
          .style("background-color", "red")
          .append("xhtml:div")
          .attr("id", "editor")
          .attr('style', 'width: 350px;height: 50px;');
    
    
        var editor = ace.edit("editor");
        editor.setTheme("ace/theme/monokai");
        editor.getSession().setMode("ace/mode/javascript");
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.9/ace.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>