Javascript NVD3图表无法计算Chrome中的图例文本长度,因为Window.getComputedStyle未正确返回字体大小 背景资料

Javascript NVD3图表无法计算Chrome中的图例文本长度,因为Window.getComputedStyle未正确返回字体大小 背景资料,javascript,css,svg,d3.js,nvd3.js,Javascript,Css,Svg,D3.js,Nvd3.js,我使用其自定义小部件框架将NVD3图表集成到EclipseRAP中。图表生成到一个div中。CSS通过在javascript中创建链接条目动态加载。我通过创建SVG/文本元素来检查CSS是否已经加载,并检查其字体大小是否正常(请参阅)。如果加载了CSS,我将创建图表 问题 由于某些原因,图表在Chrome中的渲染并不总是正确的。通常,在我的会话中,第一次正确地显示它,但第二次渲染总是错误的。对于错误的情况,我在控制台中发现: Error: Invalid value for <g>

我使用其自定义小部件框架将NVD3图表集成到EclipseRAP中。图表生成到一个div中。CSS通过在javascript中创建链接条目动态加载。我通过创建SVG/文本元素来检查CSS是否已经加载,并检查其
字体大小是否正常(请参阅)。如果加载了CSS,我将创建图表

问题 由于某些原因,图表在Chrome中的渲染并不总是正确的。通常,在我的会话中,第一次正确地显示它,但第二次渲染总是错误的。对于错误的情况,我在控制台中发现:

Error: Invalid value for <g> attribute transform="translate(NaN,5)"
我在使用
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()) )
)
结果真的很奇怪。如果图表正确,我会在控制台中找到以下内容以获得正确的布局:

这是因为布局错误:

这是错误布局的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>
控制台输出:

更新2 如果CSS是完全静态的,而不是动态加载的,那么问题也会发生

更新3
我试图在一个JSFIDLE中重现它:在一个div中使用异步创建的图表(单击一个按钮)动态创建SVG。不幸的是,错误没有出现

对不起,我对D3不是很流利,但是我脑子里想的一些想法可能会有所帮助

您是否尝试过使用d3.select()方法并以这种方式单独应用字体大小,以查看是否可以缩小字体/文本选择器组合的问题范围?可以在加载时指定一个id或类,然后使用静态样式表定义样式

在图例文本长度中断之前,您是否注意到任何奇怪的事情?删除图例和字体css是否100%都有效

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

您是否尝试过加载时的完全dom刷新或容器刷新?这会怎么样?它是否在100%的时间内渲染?还是失败

$("body").html($("body").html()); 
$("#d3div").html($("#d3div").html());
如Timo在此线程中所示

它似乎在DOM资源管理器中添加了它们,但没有在屏幕上添加 原因是html和svg的名称空间不同

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

看起来您并没有在这方面使用jQuery,但在本例中,它可能对测试有用


很抱歉听到你的疯狂虫子。希望您能找到解决方案。

非常详细的问题:我想知道答案。因为它需要一些工作来正确回答,我会考虑一个赏金当它是合格的。这似乎是一个可能的错误。看起来您正在将图表加载到“选项卡”中,是否可能在创建或显示父选项卡和子图表之间存在竞争条件?@Mark我不这么认为。出于其他原因(等待CSS加载),选项卡showup已经使用setTimeout和回调创建了图表“惰性”。据我所知,javascript是单线程的,因此,在计划执行图表创建的异步作业之前,选项卡创建肯定会完成。根据我的经验,一旦在SVG属性中添加了一个NaN,所有关于其余渲染的赌注都会落空。你能不能只发一小段代码来设置内部
的翻译?看起来这里有一个竞态条件,我以前也处理过类似的事情。我想象NaN来自下面代码中的x赋值:
g.attr('transform','translate(+(width-margin.right-legendWidth)+','+margin.top++')。也许可以尝试在那里设置断点并检查nv.d3.js或
console.log(chart.legend.width())
console.log(chart.legend.margin())
中的变量,我不使用JQuery。Adblock是有意义的。如果我用错误的名称空间创建了SVG元素,那么它就不会显示。它已经修好了,所以这不是问题。我不知道你所说的完全dom刷新是什么意思。我正在使用EclipseRAP,据我所知,这并不是一个真正的选项。使用d3操纵字体大小是我想要避免的一个选项。但真正的问题仍然存在:怎么可能,样式表是根据浏览器应用的,而样式元素不是。这就是问题所在。不管怎样,谢谢你的回答。虽然这个回答并不能真正解决问题,但我已经奖励你努力帮助解决问题。谢谢你,先生。祝你周末愉快。
<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>
document.body.className='redbody';
console.log(window.getMatchedCSSRules(document.body));
document.body.className='bluebody';
console.log("Class changed");
console.log(window.getMatchedCSSRules(document.body));
$("body").html($("body").html()); 
$("#d3div").html($("#d3div").html());