为什么将一个foreignObject附加到一个SVG中断jquery ui的大小调整?

时间:2014-01-15 23:43:16

标签: javascript angularjs svg d3.js coffeescript

我有一个用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>

好的。然后我希望能够调整它所在的容器的大小(angular directive):

.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的resize helper在屏幕上“卡住” - 但只是第一次绘制它。随后调整大小工作正常。我怀疑这是因为第二个身体标签插入了svg。据我所知,它是必需的 - 取出它导致叠加不被附加。如果我在drawOverlay的顶部放置一个返回值,则resize指令可以正常工作。所以问题出在哪里似乎很清楚,我想知道是否有人可以解释为什么会发生这种情况 - 并且可能提供修复。

1 个答案:

答案 0 :(得分:0)

如果添加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