【问题标题】:why does appending a foreignObject into an SVG break jquery ui's resize?为什么将 foreignObject 附加到 SVG 会破坏 jquery ui 的调整大小?
【发布时间】:2014-02-04 16:53:24
【问题描述】:

我有一个用 D3 构建的饼图,标记如下:

<div class="display">
  <svg height="300">
    <g transform="translate(140,125)">
      <g class="slice">
        <path fill="#3182bd" d="M-103.92304845413268,-59.99999999999993A120,120 0 0,1 -1.2862432473281782e-13,-120L0,0Z"></path>
        <text transform="translate(-30.000000000000075,-51.96152422706628)" text-anchor="middle">A</text>
      </g>
      <g class="slice">
        <path fill="#6baed6" d="M7.347638122934264e-15,120A120,120 0 0,1 -103.92304845413268,-59.99999999999993L0,0Z"></path>
        <text transform="translate(-51.961524227066306,30.00000000000002)" text-anchor="middle">B</text>
      </g>
      <g class="slice">
        <path fill="#9ecae1" d="M7.347638122934264e-15,-120A120,120 0 1,1 7.347638122934264e-15,120L0,0Z"></path>
        <text transform="translate(60,0)" text-anchor="middle">C</text>
      </g>
    </g>
  </svg>
  <div class="pieChartTooltip" style="position: absolute; z-index: 10; visibility: visible; top: 32px; left: 192px;">C: 3.00</div>
</div>

好漂亮。然后我希望能够调整它所在的容器的大小(角度指令):

.directive("resizable", [ "debounce", (debounce) ->
  restrict: "A"
  link: (scope, element, attrs) ->
    broadcastResize = (event, ui) ->
      scope.$root.$broadcast "resize", ui.element.parents(".widget"), ui.size

    debounceResize = debounce(broadcastResize, 800, false)
    element.resizable
      grid: 10
      helper: "ui-resizable-helper"
      stop: (event, ui) ->
        debounceResize event, ui
])

一切都好。接下来,我想为饼图添加一个叠加层,上面写着“示例数据”或“在 3:45 刷新”或其他类似内容。所以我将此代码添加到构建饼图(咖啡)的对象中:

drawOverlay: (msg) => 
  @logger.debug 'drawing overlay' 
  vis = d3.select(@selector + " svg ")
  @logger.warn "no svg vis found" unless vis?
  x = (@model.width / 2 ) - 75
  y = (@model.height / 2 ) - 50

  @jq(@selector + " svg foreignObject").remove()

  text = vis.append("foreignObject")
    .attr("class", "widgetOverlay")
    .attr("x", x)
    .attr("y", y)
    .attr("width", 150)
    .attr("height", 50)
    .append("xhtml:body")
    .html('<div>' + msg + '</div>') 

问题出在:添加叠加层会导致 jquery ui 的调整大小助手在屏幕上“卡住”——但仅在第一次绘制时。随后的调整大小工作正常。我怀疑这是因为在 svg 中插入了第二个 body 标签。据我所知,它是必需的——取出它会导致不附加覆盖。如果我在drawOverlay 的顶部加上一个return,resize 指令就可以正常工作。所以问题出在哪里似乎很清楚,我想知道是否有人可以解释为什么会发生这种情况——也许可以提供一个解决方案。

【问题讨论】:

    标签: javascript angularjs svg d3.js coffeescript


    【解决方案1】:

    如果添加body标签会混淆jquery.ui,那为什么不跳过body标签直接附加div呢?

    var msg = 'Hello World';
    var x = 150, y = 150;
    var svg = d3.select('body')
      .append('svg')
        .attr('width', 300)
        .attr('height', 300)
      .append("foreignObject")
        .attr("class", "widgetOverlay")
        .attr("x", x)
        .attr("y", y)
        .attr("width", 150)
        .attr("height", 50)
      .append('xhtml:div')
        .text(msg);
    

    Demo

    【讨论】:

    • 我不久前尝试过,但没有显示叠加层。您的示例在叠加层下没有任何 svg 元素,所以这可能就是您看到它的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    相关资源
    最近更新 更多