将 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 中必须将 &#xf118;
写入 \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:foreignObject
due 的好解决方案对于兼容性问题,这是一个无需使用任何技巧即可工作的答案:
.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 图表的主要内容,如果未能解决你的问题,请参考以下文章