NVD3图表无法计算Chrome中的图例文字长度,因为Window.getComputedStyle不能正确返回字体大小

背景信息

我使用它的自定义小部件框架,将NVD3图表集成到Eclipse-RAP中。 图表生成到一个div。 通过在javascript中创build链接条目来dynamic加载CSS。 我通过创build一个SVG /文本元素来检查CSS是否已经被加载,并且检查它的font-size是否正确(请参阅https://stackoverflow.com/a/7997710/337621 )。 如果CSS被加载,我创build图表。

问题

出于某种原因,图表在Chrome中无法正确显示。 通常第一次在我的会话中显示正确,但第二次它始终是错误的。 对于错误的情况,我已经在控制台中发现了这一点:

 Error: Invalid value for <g> attribute transform="translate(NaN,5)" 

如果我重绘图表(例如通过更新图表数据或resize),图例正确呈现。

预期: 在这里输入图像说明

错误的布局: 在这里输入图像说明

经过一些debugging,我find了相关的d3代码部分。 NVD3使用此函数请求SVG文本元素的字体大小:

  d3_selectionPrototype.style = function(name, value, priority) { var n = arguments.length; if (n < 3) { if (typeof name !== "string") { if (n < 2) value = ""; for (priority in name) this.each(d3_selection_style(priority, name[priority], value)); return this; } if (n < 2) return d3_window.getComputedStyle(this.node(), null).getPropertyValue(name); priority = ""; } return this.each(d3_selection_style(name, value, priority)); }; 

相关的CSS部分是这样的:

 svg text { font: normal 12px Arial; } 

我通过getComputedStyle调用添加了以下“printpoint” (条件断点,它永不停止,但打印出值)

 name == 'font-size' && ( console.log(this.node()) || console.log( d3_window.getComputedStyle(this.node(), null) ) || console.log( d3_window.getComputedStyle(this.node(), null).getPropertyValue(name) ) || console.log( window.getMatchedCSSRules(this.node()) ) ) 

结果真的很奇怪。 如果图表正确,我可以在控制台中find正确的布局: 在这里输入图像说明

而这个错误的布局: 在这里输入图像说明

这是错误布局的DOM:

 <svg id="ujdh846lhqubvvlg2jbh16s6q9" width="1896" height="361"> <g class="nvd3 nv-wrap nv-pieChart" transform="translate(20,90)"> <g> <g class="nv-pieWrap"> <g class="nvd3 nv-wrap nv-pie nv-chart-6450" transform="translate(0,0)"> <g> <g class="nv-pie" transform="translate(928,125.5)"> <g class="nv-slice" fill="#1f77b4" stroke="#1f77b4"> <path d="M6.1477269317197136e-15,-100.4A100.4,100.4 0 0,1 65.39779726531111,76.17931551835622L0,0Z"/> </g><g class="nv-slice" fill="#ff7f0e" stroke="#ff7f0e"> <path d="M65.39779726531111,76.17931551835622A100.4,100.4 0 0,1 -90.13957577290248,44.21557281638648L0,0Z"/> </g><g class="nv-slice" fill="#2ca02c" stroke="#2ca02c"> <path d="M-90.13957577290248,44.21557281638648A100.4,100.4 0 0,1 -94.15031406756688,-34.869447385619964L0,0Z"/> </g><g class="nv-slice" fill="#d62728" stroke="#d62728"> <path d="M-94.15031406756688,-34.869447385619964A100.4,100.4 0 0,1 -1.844318079515914e-14,-100.4L0,0Z"/> </g> </g><g class="nv-pieLabels" transform="translate(928,125.5)"> <g class="nv-label" transform="translate(112.95224431711586,-41.8329177051586)"> <rect rx="3" ry="3" style="stroke: rgb(255, 255, 255); fill: rgb(255, 255, 255);"/> <text style="text-anchor: middle; fill: rgb(0, 0, 0);">alma</text> </g><g class="nv-label" transform="translate(-24.246406744679096,117.98438142386297)"> <rect rx="3" ry="3" style="stroke: rgb(255, 255, 255); fill: rgb(255, 255, 255);"/> <text style="text-anchor: middle; fill: rgb(0, 0, 0);">korte</text> </g><g class="nv-label" transform="translate(-120.2954032887533,6.100692386622933)"> <rect rx="3" ry="3" style="stroke: rgb(255, 255, 255); fill: rgb(255, 255, 255);"/> <text style="text-anchor: middle; fill: rgb(0, 0, 0);">szilva</text> </g><g class="nv-label" transform="translate(-68.80925650816773,-98.86095649341644)"> <rect rx="3" ry="3" style="stroke: rgb(255, 255, 255); fill: rgb(255, 255, 255);"/> <text style="text-anchor: middle; fill: rgb(0, 0, 0);">paradicsom</text> </g> </g> </g> </g> </g><g class="nv-legendWrap" transform="translate(0,-90)"> <g class="nvd3 nv-legend" transform="translate(0,5)"> <g transform="translate(NaN,5)"> <g class="nv-series" transform="translate(0,5)"> <circle class="nv-legend-symbol" r="5" style="stroke-width: 2px; fill: rgb(31, 119, 180); stroke: rgb(31, 119, 180);"/> <text text-anchor="start" class="nv-legend-text" dy=".32em" dx="8">alma</text> </g><g class="nv-series" transform="translate(0,25)"> <circle class="nv-legend-symbol" r="5" style="stroke-width: 2px; fill: rgb(255, 127, 14); stroke: rgb(255, 127, 14);"/> <text text-anchor="start" class="nv-legend-text" dy=".32em" dx="8">korte</text> </g><g class="nv-series" transform="translate(0,45)"> <circle class="nv-legend-symbol" r="5" style="stroke-width: 2px; fill: rgb(44, 160, 44); stroke: rgb(44, 160, 44);"/> <text text-anchor="start" class="nv-legend-text" dy=".32em" dx="8">szilva</text> </g><g class="nv-series" transform="translate(0,65)"> <circle class="nv-legend-symbol" r="5" style="stroke-width: 2px; fill: rgb(125, 0, 0); stroke: rgb(125, 0, 0);"/> <text text-anchor="start" class="nv-legend-text" dy=".32em" dx="8">paradicsom</text> </g> </g> </g> </g> </g> </g> </svg> 

怎么可能,一旦我的SVG /文字没有计算风格的字体大小,但它总是有一个应用CSS规则的字体大小?

Chrome中是否存在一些已知的错误?

请注意,在Firefox中一切正常。

环境细节

Chrome 39.0.2171.71(64位)

Kubuntu 3.13.0-29-generic

更新

我以为我受到这种浏览器“行为”的影响: 我如何改变console.log的默认行为? (*在Safari浏览器错误控制台,没有附加*) 。 这意味着控制台不会在日志条目的时间点显示对象的状态,而是指向当前状态。 所以我在这里做了一个小实验: http : //jsfiddle.net/hdv7ty6L/ 。 我从JavaScript中更改类,并检查规则列表是否在控制台中更改。 这似乎是规则列表的快照。 所以还是没有线索,这里有什么错误:)

testing代码:

 document.body.className='redbody'; console.log(window.getMatchedCSSRules(document.body)); document.body.className='bluebody'; console.log("Class changed"); console.log(window.getMatchedCSSRules(document.body)); 

控制台输出: 在这里输入图像说明

更新2

如果CSS是完全静态的并且不是dynamic加载的,问题也会发生。

更新3

我试图在jsfiddle中重现它:dynamic创build的SVG内的asynchronous创build图表(点击button)。 错误不显示不幸。 https://jsfiddle.net/ewsb4d9k/1/

对不起,我对D3并不是很stream利,但是我头脑中的一些想法可能会有所帮助。

你有没有尝试过使用d3.select()方法,只用这种方式的字体大小,看看你是否可以缩小字体/文本select器组合的问题? 也许分配负载的id或类,然后使用静态样式表定义您的样式。

你有没有注意到在传奇文字长度破裂之前有什么奇怪的东西? 是否删除图例和字体的CSS工作100%的时间?

我注意到你正在使用adblock。 如果你还没有,那么值得一试。 这个插件有时会做一些疯狂的事情。

你有没有尝试完整的DOM刷新或容器刷新,加载? 这发生了什么? 它是100%的时间吗? 仍然失败?

 $("body").html($("body").html()); $("#d3div").html($("#d3div").html()); 

从Timo在这个线程中显示jQuery的附加不工作与SVG元素?

“它似乎把它们添加到DOM浏览器,但不是在屏幕上”,原因是对于html和svg不同的命名空间。

最简单的解决方法是“刷新”整个SVG。

这看起来不像你正在使用jQuery,但在这种情况下,它可能是有用的testing。

很抱歉听到你疯狂的错误。 希望你find一个解决scheme。