将 FontAwesome 图标添加到 D3 图表

Posted

技术标签:

【中文标题】将 FontAwesome 图标添加到 D3 图表【英文标题】:Adding FontAwesome icons to a D3 graph 【发布时间】:2013-08-27 07:50:28 【问题描述】:

我试图在我的 D3 节点中设置一个带有 FontAwesome 的图标,而不是文本。这是原来的实现,带文字:

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);

这正是我想要做的,但它不适用于 FontAwesome 使用的 <i> 元素。

【问题讨论】:

【参考方案1】:

您需要在普通文本元素中使用正确的 Unicode,然后将 font-family 设置为“FontAwesome”,如下所示:

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

这个确切的代码将呈现一个“icon-smile”图标。所有 FontAwesome 图标的 unicode 可以在这里找到:

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

请注意,您需要将备忘单中的代码从 html/CSS unicode 格式调整为 javascript unicode 格式,以便在您的 javascript 中必须将  写入 \uf118

【讨论】:

谢谢!这完美地工作。我陷入了几个陷阱。首先值得注意的是,<text> 是一个 svg 标记(我将其查找为 html 标记)。我在将节点内的图标居中时遇到了问题(在我的例子中是圆圈) - 还有样式,因为 CSS 优先于属性,并且我为 <text> 元素设置了样式。作为参考,我将粘贴我的最终解决方案作为答案。 它对我不起作用...我采用了与上面列出的完全相同的代码,但我没有按预期得到绘图。我需要在本地安装字体吗?我正在使用 FontAws 的 cdn 版本,想知道这是否与它有关(它在其他任何地方都可以完美地工作,但 D3) 感谢 Carles,我通过将 attr 更改为 font-family 和 font-size 的样式来使其工作 此解决方案不适用于Font Awesome 5.6.3。您还需要设置 .attr('font-family', 'Font Awesome 5 Free').attr('font-weight', 900) 如何使用FAB或FAR图标?【参考方案2】:

感谢所有回复。我的最终解决方案基于 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 可以正确处理事件。

【讨论】:

嗨,你能把为你做这件事的代码的 sn-p 发给我吗?出于某种原因,当我使用您在上面附加的代码时,我没有得到任何图像来显示?你是如何存储图像的unicode的?谢谢 您可能需要ICON_UNICODE 数组。 这是 font-awesome 4.0.3 中的 ICON_UNICODE 对象:gist.github.com/forresto/8254791 @jeckyll2hide 快速说明: .attr 应该是 .style 以显示图标。这是从 D3.JS 版本 3.5.3 开始的。试图只编辑您的答案,但这是不行的。 谢谢,这行得通。在查看了其他答案之后,我仍然错过了我最终在您的示例代码中偶然发现的字体系列设置。终生基于 *** 的编程?【参考方案3】:

我真的是 d3 的新手,但是 font awesome 可以通过使用 class 属性来设置 <i> 元素的样式。

我发现的唯一方法是附加 foreignObject 并在其上设置 font awesome 所需的相关 HTML。

参考:

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/

【讨论】:

您的解决方案很有趣,但是有一个异物会使样式变得复杂。例如,body CSS 样式会自动应用(在我的例子中,这使得图标的背景在节点图中可见)。我更喜欢没有这个foreignObject的解决方案,但我不知道这是否可能。 我正在检查是否可以通过其他方式进行 谢谢。 foreignObject 的另一个问题是它不转发事件。您可以在此处看到该问题:jsbin.com/eFAZABe/6:当您尝试链接节点时,该图标会阻止 onMouseOver。在原始问题中,我添加了一个示例的链接,该示例使用图像来实现类似的效果(但我需要字体真棒图标) 对不起,尝试了tspan等,但我发现的唯一方法是使用foreignObject 因为还没有人提到浏览器对异物的不完整支持:caniuse.com/#feat=svg-html【参考方案4】:

鉴于其他答案不再起作用(因为同时 d3js 已更新)并且因为它不是是使用svg:foreignObjectdue 的好解决方案对于兼容性问题,这是一个无需使用任何技巧即可工作的答案:

.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)

这是一个工作示例(单击“运行代码 sn-p”,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>

【讨论】:

赞!此解决方案也适用于 Font Awesome 5.6.3 并且从 4 迁移不需要任何额外的努力 @AhmadKarim D3.js 版本已过时。我添加了一个较新的版本,现在它又可以工作了,见上文。【参考方案5】:

我知道这个问题很老了,已经解决了,但是 - 这对我今天有用。

来自this site

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>')

【讨论】:

【参考方案6】:

根据 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' );

【讨论】:

【参考方案7】:

按如下方式使用 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 有所帮助

【讨论】:

【参考方案8】:

对于那些用力敲打头的人。 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

【讨论】:

【参考方案9】:

对于那些想在 D3 中使用来自 FontAwesome 的 svg 图标的人,这个 sn-p 应该可以工作:

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

这里唯一的缺点是宽度和高度不是从 CSS 继承的。好消息是 d3 和 jquery 的类切换按预期工作。

点击切换演示:https://jsfiddle.net/diafour/6fagxpt0/

【讨论】:

以上是关于将 FontAwesome 图标添加到 D3 图表的主要内容,如果未能解决你的问题,请参考以下文章

在d3.js时间轴图表中添加图像而不是点

在输入占位符文本中使用 Angular fontawesome 图标

将 y 轴网格线添加到 D3 甘特图

将fontawesome 图标变大

单击geojson多边形到传单地图时添加的更新d3图表

d3.js ----面积图表