Trying to put a border around some SVG text, and I am getting varying results.
HTML: (with the mute class)
<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));
})
Here we have the X
without the mute class
Here we have the X
with the mute class but without the border
This is what we are trying to get the border to look like
Note: its parent is a group, not an HTML element.
JS Fiddle: http://jsfiddle.net/chrisfrisina/yuRyr/5/
With newer versions of d3.js, there's no interpolate()
function on the line generator (reference: "Interpolate" is not a function), so I somewhat modified Alvin K's answer as shown in the code below (Typescript). In particular, the code is used to simulate a hover effect on an SVG text.
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")
})
})
PS: it's not necessary to use call()
on the selection, you could just call on()
directly, however in my actual code, I refactored the callback into a class method.
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>
SVG elements don't support the CSS border property as you have discovered. Your options are
<rect>
around the text as a border<svg>
element if its parent is a html element. The outer <svg>
element is a replaced element and will support the CSS border property.To draw a rect around text on click, update the code to:
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");
})
On this 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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With