SVG文本周围的矩形边框

15
尝试在一些SVG文本周围加边框,但结果却不尽相同。(有静音类的HTML代码)
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <text x="37.5" y="37.5" class="ablate-x mute">X</text>
</svg>

CSS:

.ablate-x {
   font-size: 24px;
   color: gray;
   opacity: 0.5;
   font-weight: 900;
   cursor: hand;
   cursor: pointer;
}

.mute {
   opacity: 1;
   fill: red;
   stroke: red;
   stroke-width: 2px;
   /* we tried border: 2px solid red;   but it didn't work */
}

D3.js:

.on("click", function(d) {
    var selection = d3.select(this);
    selection.classed("mute", (selection.classed("mute") ? false : true));
 })

这里是没有静音类的 X 灰色
这里是有静音类但没有边框的 X 红色
这就是我们试图让边框看起来像的样子 带边框的红色
注意:其父级是一个组,而不是HTML元素。
JS Fiddle: http://jsfiddle.net/chrisfrisina/yuRyr/5/

这个问题和这个问题应该会有所帮助:This questionthis question - Lars Kotthoff
3个回答

21

正如您发现的那样,SVG元素不支持CSS边框属性。您有以下两个选项:

  1. 绘制一个红色的 <rect> 围绕文本作为边框
  2. 如果其父元素是html元素,则在外部的<svg>元素上添加边框。外部的<svg>元素是替代元素,将支持CSS边框属性。

1
所有 CSS 属性中有哪些是 SVG 不支持的? - Ankur Bajaj

13

为了在单击时绘制文本周围的矩形,请更新代码:

var svgcanvas = d3.select('svg');

$("#xc").on("click", function (d) {
    var selection = d3.select(this);
    var rect = this.getBBox();
    var offset = 2; // enlarge rect box 2 px on left & right side
    selection.classed("mute", (selection.classed("mute") ? false : true));

    pathinfo = [
        {x: rect.x-offset, y: rect.y }, 
        {x: rect.x+offset + rect.width, y: rect.y}, 
        {x: rect.x+offset + rect.width, y: rect.y + rect.height }, 
        {x: rect.x-offset, y: rect.y + rect.height},
        {x: rect.x-offset, y: rect.y },
    ];

    // Specify the function for generating path data
    var d3line = d3.svg.line()
        .x(function(d){return d.x;})
        .y(function(d){return d.y;})
        .interpolate("linear"); 
    // Draw the line
    svgcanvas.append("svg:path")
        .attr("d", d3line(pathinfo))
        .style("stroke-width", 1)
        .style("stroke", "red")
        .style("fill", "none");

})

在这个HTML上:

    <!DOCTYPE html>
    <html>
    <head>
        <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    </head>
    <body>
        <svg width="720" height="720">
            <text x="37.5" y="37.5" id="xc">X</text>
        </svg>
    </body>
    </html>

我一开始尝试定位一个矩形。我发现这个解决方案更加优雅。谢谢! - jarandaf

2

随着d3.js的更新版本,线条生成器上已经没有interpolate()函数(参考:"Interpolate" is not a function),所以我对Alvin K的答案进行了一些修改,如下所示(使用Typescript)。特别地,该代码用于模拟SVG文本的悬停效果。

    const group = d3.select(/* your node */)
    group
        .append("rect")
        .attr("stroke", "none")
        .attr("fill", "none")

    group
        .append("text")
        .call((node) => {
            node.on("mouseenter", function(this: any) {
                const rect = this.getBBox()
                d3.select(this.parentNode)
                    .select("rect")
                    .attr("x", rect.x - offset)
                    .attr("y", rect.y - offset)
                    .attr("width", rect.width + offset * 2)
                    .attr("height", rect.height + offset * 2)
                    .style("stroke-width", 1)
                    .style("stroke", "black")
                    .style("stroke-dasharray", "4")
                    .style("fill", "none");
                })
            node.on("mouseleave", function(this: any) {
                d3.select(this.parentNode)
                    .select("rect")
                    .style("stroke", "none")
            })
        })

提示:在所选内容上不必使用call(),直接调用on()即可。但是,在我的实际代码中,我将回调函数重构为类方法。

var offset = 5
onload();

function onload() {
    var svg = d3.select("body")
                .append("svg")
                .attr("width", 200)
                .attr("height", 200)

    const group = svg
        .append("g")
        .attr("transform", "translate(10, 40)")
    group
        .append("rect")
        .attr("stroke", "none")
        .attr("fill", "none")

    group
        .append("text")
        .attr("fill", "black")
        .attr("font-weight", 600)
        .attr("font-size", "16px")
        .text("HOVER ON ME")
        .call((node) => {
            node.on("mouseenter", function() {
                const rect = this.getBBox()
                d3.select(this.parentNode)
                    .select("rect")
                    .attr("x", rect.x - offset)
                    .attr("y", rect.y - offset)
                    .attr("width", rect.width + offset * 2)
                    .attr("height", rect.height + offset * 2)
                    .style("stroke-width", 1)
                    .style("stroke", "black")
                    .style("stroke-dasharray", "4")
                    .style("fill", "none");
                })
            node.on("mouseleave", function() {
                d3.select(this.parentNode)
                    .select("rect")
                    .style("stroke", "none")
            })
        })
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接