Добавление значков FontAwesome на график D3

Я пытаюсь установить значок с FontAwesome вместо текста в моих узлах D3. Это оригинальная реализация с текстом:

g.append('svg:text')
    .attr('x', 0)
    .attr('y', 4)
    .attr('class', 'id')
    .text(function(d) { return d.label; });

А теперь пробую с иконками:

g.append('svg:i')
   .attr('x', 0)
   .attr('y', 4)
   .attr('class', 'id icon-fixed-width icon-user');

Но это не работает, несмотря на то, что разметка правильная, и правила CSS правильно соблюдаются: иконки не видны.

Есть идеи, почему?

Вот соответствующий jsbin

РЕДАКТИРОВАТЬ

Я нашел эту альтернативу для вставки изображений: http://bl.ocks.org/mbostock/950642

node.append("image")
    .attr("xlink:href", "https://github.com/favicon.ico")
    .attr("x", -8)
    .attr("y", -8)
    .attr("width", 16)
    .attr("height", 16);

Это именно то, что я хочу сделать, но это не работает с элементами <i>, используемыми FontAwesome.


person blueFast    schedule 24.08.2013    source источник


Ответы (9)


Вам нужно использовать правильный Unicode внутри обычного текстового элемента, а затем установить для семейства шрифтов значение «FontAwesome» следующим образом:

 node.append('text')
    .attr('font-family', 'FontAwesome')
    .attr('font-size', function(d) { return d.size+'em'} )
    .text(function(d) { return '\uf118' }); 

Этот точный код будет отображать значок «значок-улыбка». Юникоды для всех иконок FontAwesome можно найти здесь:

http://fortawesome.github.io/Font-Awesome/cheatsheet/

Имейте в виду, что вам необходимо адаптировать коды в шпаргалке из формата юникода HTML/CSS в формат юникода Javascript, чтобы &#xf118; должно было быть написано \uf118 в вашем javascript.

person Carles Andres    schedule 15.10.2013
comment
Спасибо! Это работает отлично. Я попал в несколько ловушек. Во-первых, стоит отметить, что <text> — это тег svg (я искал его как тег html). У меня были проблемы с центрированием значков внутри узлов (кругов в моем случае). Также со стилем, поскольку CSS имеет приоритет над атрибутами, и у меня был набор стилей для элементов <text>. Для справки я вставлю свое окончательное решение в качестве ответа. - person blueFast; 10.11.2013
comment
у меня это не работает ... я взял точно такой же код, как указано выше, и я не получаю рисунок, как ожидалось. мне нужно установить шрифты локально? я использую cdn-версию FontAws и задаюсь вопросом, имеет ли это какое-то отношение к ней (она отлично работает везде, кроме D3) - person Or A; 04.12.2013
comment
Спасибо, Карлес, я заставил его работать, изменив атрибут на стиль для семейства шрифтов и размера шрифта. - person mhd; 01.06.2016
comment
Это решение НЕ работает с Font Awesome 5.6.3. Вам также нужно будет установить .attr('font-family', 'Font Awesome 5 Free') и .attr('font-weight', 900) - person Ricardo; 23.01.2019
comment
Как использовать значок FAB или FAR? - person Neo; 21.06.2021

Спасибо всем, что ответили. Мое окончательное решение основано на ответе CarlesAndres:

g.append('text')
    .attr('text-anchor', 'middle')
    .attr('dominant-baseline', 'central')
    .attr('font-family', 'FontAwesome')
    .attr('font-size', '20px')
    .text(function(d) { return ICON_UNICODE[d.nodeType]; });

Будьте осторожны с вашим CSS: он имеет приоритет над атрибутами SVG.

И вот как это выглядит:

График узлов

Хорошая вещь в этом, по сравнению с решением foreignObject, заключается в том, что события правильно обрабатываются D3.

person blueFast    schedule 10.11.2013
comment
привет, не могли бы вы прислать мне фрагмент кода, который сделал это для вас? по какой-то причине, когда я использую код, который вы прикрепили выше, я не получаю изображения для показа? как вы сохранили юникод изображений? Спасибо - person Or A; 04.12.2013
comment
Вероятно, вам нужен массив ICON_UNICODE. - person forresto; 04.01.2014
comment
Вот объект ICON_UNICODE в версии font-awesome 4.0.3: gist.github.com/forresto/8254791 - person forresto; 04.01.2014
comment
Краткое примечание @ jeckyll2hide: .attr должен быть .style, чтобы отображались значки. Это начиная с D3.JS версии 3.5.3. Пытался просто отредактировать ваш ответ, но это не помогло. - person Delicia Brummitt; 12.01.2015
comment
@jeckyll2hide «Пушистый» — идеальное слово для этого. Согласно D3 wiki, для установки атрибутов стиля CSS следует использовать стиль. Что применимо к семейству шрифтов и размеру шрифта здесь< /а>. это документация W3C. Текстовая привязка и доминирующая базовая линия перечислены как атрибуты SVG согласно Mozilla< /а>. - person Delicia Brummitt; 13.01.2015
comment
Спасибо, это сработало. Посмотрев на другие ответы, мне все еще не хватало настройки семейства шрифтов, на которую я наконец наткнулся в вашем примере кода. Программирование на основе Stackoverflow для жизни ???? - person Pirkka Esko; 15.11.2016

Я действительно новичок в d3, но шрифт awesome работает, стилизуя элемент <i> с атрибутом класса.

Единственный способ, который я нашел, - это добавить foreignObject и установить на нем соответствующий HTML-код, необходимый для шрифта awesome.

Ссылка:

https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject?redirectlocale=en-US&redirectslug=SVG%2FElement%2FforeignObject

http://fortawesome.github.io/Font-Awesome/examples/

Код:

g.append('svg:foreignObject')
    .attr("width", 100)
    .attr("height", 100)
    .append("xhtml:body")
    .html('<i class="icon-fixed-width icon-user"></i>');

Демонстрация: http://jsbin.com/eFAZABe/3/

person Irvin Dominin    schedule 24.08.2013
comment
Ваше решение интересное, но наличие постороннего предмета усложняет оформление. Например, стили CSS тела применяются автоматически (в моем случае это делает фон значка видимым в графе узлов). Я бы предпочел решение без этого ForeignObject, но я не знаю, возможно ли это вообще. - person blueFast; 24.08.2013
comment
Я проверяю, возможно ли это другим способом - person Irvin Dominin; 24.08.2013
comment
Спасибо. Другая проблема с ForeignObject заключается в том, что он не передает события. Вы можете увидеть эту проблему здесь: jsbin.com/eFAZABe/6: когда вы пытаетесь связать узлы , значок предотвращает onMouseOver. В исходном вопросе я добавил ссылку на пример, в котором используются изображения для достижения аналогичного эффекта (но мне нужны потрясающие значки шрифтов) - person blueFast; 24.08.2013
comment
Извините, пробовал tspan и другие, но единственный способ, который я нашел, - это использовать foreignObject - person Irvin Dominin; 24.08.2013
comment
потому что никто еще не упомянул о неоднородной поддержке браузером постороннего объекта: caniuse.com/#feat=svg- html - person ptim; 21.06.2015

Учитывая, что другие ответы больше не работают (поскольку тем временем d3js был обновлен) и поскольку это не хорошее решение для использования svg:foreignObject из-за проблем совместимости, здесь это ответ, который работает без использования каких-либо хаков:

.append("text")      // Append a text element
.attr("class", "fa") // Give it the font-awesome class
.text("\uf005");     // Specify your icon in unicode (https://fontawesome.com/cheatsheet)

Вот рабочий пример (щелкните «Выполнить фрагмент кода», и код d3 выведет три звездочки):

var icons = [1, 2, 3];

d3.select("body")
  .selectAll(".text")
  .data(icons)
  .enter()
  .append("text")       // Append a text element
  .attr("class", "fa")  // Give it the font-awesome class
  .text("\uf005");      // Specify your icon in unicode
<link href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.16.0/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

person Jean-Paul    schedule 16.09.2018
comment
Слава! Это решение также работает на Font Awesome 5.6.3 И при переносе от 4 не требует дополнительных усилий - person Ricardo; 23.01.2019
comment
@AhmadKarim Версия D3.js устарела. Я добавил более новую версию, и теперь она снова работает, см. выше. - person Jean-Paul; 20.08.2020

Я знаю, что этот вопрос старый, он был решен, но сегодня это сработало для меня.

С этого сайта

svg.append('svg:foreignObject')
    .attr("width", 50)
    .attr("height", 50)
    .append("xhtml:body")
    .html('<i class="fa fa-user"></i>');

Но для своей диаграммы я удалил добавление xhtml:body, иначе это не позволило бы мне установить координаты x и y.

Элемент примет ширину и высоту установленного вами шрифта.

d3.select('svg')
    .append('svg:foreignObject')
    .attr('class', 'handle')
    .attr('x',  +getLeftBarPosition(i+1, 'handle')[0] + +getLeftBarPosition(i+1, 'handle')[1])
    .attr('y', state.barHeight/2)
    .html('<i class="fa fa-user"></i>')
person JasTonAChair    schedule 21.04.2016

Просто чтобы добавить сюда код, который сработал для меня, основываясь на ответе CarlesAndres и комментарии mhd:

node.append("text")
    .attr("style","font-family:FontAwesome;")
    .attr('font-size', "50px" )
    .attr("x", 440)
    .attr("y", 440)
    .text(function(d) { return '\uf118' });
person Jason    schedule 24.05.2017

Версии Font Awesome 4.x не поддерживаются, если мы используем следующее:

svg.append('text')
   .attr('x', 15)
   .attr('y', -17)
   .attr('fill', 'black')
   .attr('font-family', 'FontAwesome')
   .attr('font-size', function (d) { return '20px' })
   .text(function (d) { return '\uf2b9' });

так замени это

.attr('font-family', 'FontAwesome')

с участием

.attr("class", "fa")

Надеюсь, это поможет для FA 4.x

person Navin    schedule 30.04.2020

Для тех, кто сильно бьется головой. D3 - 6.2.0 и FontAwesome - 5.13.0 Ниже работало

nodeEnter.append('text')
    .attr('width', "10px" ).attr('height', "10px" ) // this will set the height and width
    .attr("class","fas fa-adjust") // Font Awesome class, any
    .attr("x", 15) // for placement on x axis
    .attr("y",-5); // for placement on y axis
person Aadam    schedule 28.09.2020

Для тех, кто хочет использовать значки svg от FontAwesome с D3, этот фрагмент должен работать:

btnGroup.append("g")
  .attr("width", 16)
  .attr("height", 16)
  .attr("class", "fas fa-check-square");

Единственный недостаток здесь в том, что ширина и высота не наследуются от CSS. Хорошей новостью является то, что переключение классов работает, как и ожидалось, с d3 и jquery.

Демонстрация с переключением по клику: https://jsfiddle.net/diafour/6fagxpt0/

person diafour    schedule 05.10.2020