Подтвердить что ты не робот

В диаграмме NVD3 невозможно вычислить длину текста легенды в Chrome, так как Window.getComputedStyle не вернет размер шрифта правильно

Фоновая информация

Я создал интеграцию диаграмм 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)"

Если я делаю перерисовку диаграммы (например, путем обновления данных диаграммы или изменения размера), легенда отображается правильно.

Ожидаемый: enter image description here

Неправильный макет: enter image description here

После некоторой отладки я нашел соответствующую часть кода 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()) )
)

Результат действительно странный. Если диаграмма верна, я нахожу это в консоли для правильной компоновки: enter image description here

И это для неправильного расположения: enter image description here

Это 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));

Выход консоли: enter image description here

Обновление 2

Проблема также возникает, если CSS полностью статичен и не загружен динамически.

Обновление 3

Я попытался воспроизвести его в jsfiddle: динамически созданный SVG внутри div с асинхронно созданной диаграммой (onclick кнопки). К сожалению, ошибка не отображается. https://jsfiddle.net/ewsb4d9k/1/

4b9b3361

Ответ 1

Извините, я не очень свободно говорю с D3, но несколько идей с головы, которые могут быть полезны.

Пробовали ли вы использовать метод d3.select() и применяли только размер шрифта таким образом, чтобы увидеть, можете ли вы сузить, что комбинация селектора шрифтов/текста является проблемой? Возможно, назначьте id или класс при загрузке, а затем определите свои стили, используя статическую таблицу стилей.

Заметили ли вы что-нибудь странное до того, как сломать текст легенды? Удаляет ли легенда и шрифт css 100% времени?

Я заметил, что вы используете adblock. Это стоит того, чтобы отключить его, если вы еще этого не сделали. Этот плагин иногда делает сумасшедшие вещи.

Вы пытались обновить дом или обновление контейнера при загрузке? Что с этим происходит? Оказывает ли это 100% времени? Все еще не удается?

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

как показано в Timo в этом потоке Приложение jquery не работает с элементом svg?

"он, кажется, добавляет их в DOM-проводник, но не на экране" и причиной этого являются разные пространства имен для html и svg.

Простейшим обходным решением является "обновление" всего svg.

Не похоже, что вы работали с jQuery, но в этом случае это может быть полезно для тестирования.

Прошу прощения за вашу безумную ошибку. Надеюсь, вы найдете решение.