Фоновая информация
Я создал интеграцию диаграмм NVD3 в Eclipse-RAP, используя свою собственную структуру виджетов. Диаграмма сгенерирована в div. CSS загружается динамически, создавая ссылку в javascript. Я проверяю, загружен ли CSS, создавая элемент SVG/text, и я проверяю, нормально ли его font-size
(см. qaru.site/info/110759/...). Если CSS загружен, я создаю диаграмму.
Проблема
По какой-то причине диаграмма не всегда корректно отображается в Chrome. Обычно первый раз в моей сессии он отображается правильно, но второй раз всегда визуализируется неправильно. Для неправильного случая я нашел это в консоли:
Error: Invalid value for <g> attribute transform="translate(NaN,5)"
Если я делаю перерисовку диаграммы (например, путем обновления данных диаграммы или изменения размера), легенда отображается правильно.
Ожидаемый:
Неправильный макет:
После некоторой отладки я нашел соответствующую часть кода d3. NVD3 запрашивает размер шрифта для элемента SVG Text, используя эту функцию:
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
:
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>
Как может случиться так, что когда SVG/Text не будет иметь размер шрифта в вычисленном стиле, но он всегда имеет размер шрифта в одном из примененных правил CSS?
Есть ли какая-то известная ошибка в Chrome для этого?
Обратите внимание, что в Firefox все работает нормально.
Сведения об окружающей среде
Chrome 39.0.2171.71 (64-разрядный)
Kubuntu 3.13.0-29-generic
Update
Я думал, что меня поражает это "поведение" браузеров: Как изменить поведение по умолчанию console.log? (* Ошибка консоли в сафари, без добавления *). Это означает, что консоль не отображает состояние объекта в момент времени записи в журнале, но относится к текущему состоянию. Поэтому я сделал небольшой эксперимент здесь: http://jsfiddle.net/hdv7ty6L/. Я меняю класс на 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: динамически созданный SVG внутри div с асинхронно созданной диаграммой (onclick кнопки). К сожалению, ошибка не отображается. https://jsfiddle.net/ewsb4d9k/1/