首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >由于Window.getComputedStyle未正确返回字体大小,NVD3图表无法计算Chrome中的图例文本长度

由于Window.getComputedStyle未正确返回字体大小,NVD3图表无法计算Chrome中的图例文本长度
EN

Stack Overflow用户
提问于 2015-01-07 19:53:02
回答 1查看 2.4K关注 0票数 49

背景信息

我使用Eclipse-RAP的自定义小部件框架创建了一个将NVD3图表集成到其中的工具。图表被生成到一个div中。通过在javascript中创建链接条目来动态加载CSS。我通过创建一个SVG/text元素来检查CSS是否已经加载,并检查它的font-size是否正常(参见https://stackoverflow.com/a/7997710/337621)。如果加载了CSS,我将创建图表。

问题

由于某些原因,图表在Chrome中并不总是正确呈现。通常第一次在我的会话中是正确的,但第二次总是错误的。对于错误的情况,我在控制台中找到了以下内容:

代码语言:javascript
复制
Error: Invalid value for <g> attribute transform="translate(NaN,5)"

如果我使图表重新绘制(例如,通过更新图表数据或调整大小),则图例将正确呈现。

期望值:

布局错误:

经过一些调试,我找到了相关的d3代码部分。NVD3使用以下函数询问SVG文本元素的字体大小:

代码语言:javascript
复制
  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部分如下:

代码语言:javascript
复制
svg text {
  font: normal 12px Arial;
}

我在使用getComputedStyle调用的行上添加了以下“打印点”(条件断点,它从不停止,但打印值):

代码语言:javascript
复制
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:

代码语言:javascript
复制
<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中有什么已知的bug吗?

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

环境详细信息

Chrome 39.0.2171.71 (64位)

Kubuntu 3.13.0-29-通用

更新

我想我受到了浏览器的这种“行为”的影响:How can I change the default behavior of console.log? (*Error console in safari, no add-on*)。这意味着控制台不会显示对象在日志条目时间点的状态,而是引用当前状态。所以我在这里做了一个小实验:http://jsfiddle.net/hdv7ty6L/。我在javascript中更改了类,并在控制台中检查规则列表是否更改。它似乎是规则列表的快照。所以还是没有线索,这里出了什么问题:)

测试代码:

代码语言:javascript
复制
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是完全静态的,并且不是动态加载的,也会出现这个问题。

更新3

我尝试在jsfiddle中重现它:在div中动态创建SVG,并使用异步创建的图表(只需单击一个按钮)。不幸的是,错误没有显示出来。https://jsfiddle.net/ewsb4d9k/1/

EN

回答 1

Stack Overflow用户

发布于 2015-04-23 11:22:25

对不起,我对D3不是很熟悉,但我有几个想法可能会对我有所帮助。

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

在图例文本长度中断之前,你有没有注意到什么奇怪的事情?移除图例和字体css是否100%有效?

我注意到你在用广告区块。如果你还没有禁用它,那也值得一试。这个插件有时会做一些疯狂的事情。

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

代码语言:javascript
复制
$("body").html($("body").html()); 
$("#d3div").html($("#d3div").html());

如Timo在此线程jquery's append not working with svg element?中所示

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

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

看起来您并没有使用jQuery来处理这个问题,但在这种情况下,它可能对测试很有用。

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

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27818936

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档