Skip to content

Instantly share code, notes, and snippets.

@Lulkafe
Created April 22, 2016 23:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lulkafe/95a63ddea80d4d02cc4ab8bedd48dfd8 to your computer and use it in GitHub Desktop.
Save Lulkafe/95a63ddea80d4d02cc4ab8bedd48dfd8 to your computer and use it in GitHub Desktop.
Reusable d3 Close button
function d3CloseButton () {
var size = 20,
x = 0,
y = 0,
rx = 0,
ry = 0,
isCircle = false,
isBorderShown = false,
borderStrokeWidth = 1.5,
crossStrokeWidth = 1.5,
g,
event;
function button (selection) {
//Styling for the border of the button
var buttonStyle = {
"fill-opacity": 0,
"stroke-width": borderStrokeWidth,
"stroke": (isBorderShown)? "none" : "black" },
//for the cross
crossStyle = {
"stroke-width": crossStrokeWidth,
"stroke": "black"
},
r = size / 2,
ofs = size / 6,
cross;
g = selection.append("g").on("click", event);
cross = g.append("g");
if (isCircle) {
g.append("circle")
.attr("cx", x)
.attr("cy", y)
.attr("r", r)
.style(buttonStyle);
cross.append("line")
.attr("x1", x - r + ofs)
.attr("y1", y)
.attr("x2", x + r - ofs)
.attr("y2", y);
cross.append("line")
.attr("x1", x)
.attr("y1", y - r + ofs)
.attr("x2", x)
.attr("y2", y + r - ofs);
// Make '+' to 'x'
cross.attr("transform", "rotate (45," + x + "," + y + ")");
} else {
g.append("rect")
.attr("x", x)
.attr("y", y)
.attr("rx", rx)
.attr("ry", ry)
.attr("width", size)
.attr("height", size)
.style(buttonStyle);
cross.append("line")
.attr("x1", x + ofs)
.attr("y1", y + ofs)
.attr("x2", (x + size) - ofs)
.attr("y2", (y + size) - ofs);
cross.append("line")
.attr("x1", (x + size) - ofs)
.attr("y1", y + ofs)
.attr("x2", x + ofs)
.attr("y2", (y + size) - ofs);
}
cross.style(crossStyle)
}
button.x = function (val) {
x = val;
return button;
}
button.y = function (val) {
y = val;
return button;
}
button.size = function (val) {
size = val;
return button;
}
button.rx = function (val) {
rx = val;
return button;
}
button.ry = function (val) {
ry = val;
return button;
}
button.borderStrokeWidth = function (val) {
borderStrokeWidth = val;
return button;
}
button.crossStrokeWidth = function (val) {
crossStrokeWidth = val;
return button;
}
//If true, the border of the button becomes a circle instead of a rectangle
button.isCircle = function (val) {
isCircle = val;
return button;
}
button.isBorderShown = function (val) {
isBorderShown = val;
return button;
}
button.clickEvent = function (val) {
event = val;
return button;
}
//Remove the whole button if one already exists
button.remove = function () {
if (g) {
g.remove();
g = undefined;
}
return button;
}
return button;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="d3CloseButton.js"></script>
<title>Title</title>
</head>
<body>
<div id="vis"></div>
<script>
var height = 500,
width = 700,
size = 100,
svg = d3.select("#vis").append("svg").attr("width", width).attr("height", height),
xs = [50, 200, 350],
clsbtn1 = new d3CloseButton(),
clsbtn2 = new d3CloseButton(),
clsbtn3 = new d3CloseButton();
svg.append("text").attr("x", 30).attr("y", 20).text("Click close buttons");
//Setting up each close button. Default values are already set, so you can ignore this step
clsbtn1.size(30).isCircle(true).borderStrokeWidth(3).crossStrokeWidth(5);
clsbtn2.size(20).rx(4).ry(4);
/* The remaining part is just for demonstration
The only necessary step is to do selection.call(closeButton_object)
(In this example, the corresponding part is, for example, "g.call(clsbtn1)"); */
var gUpper = svg.append("g").selectAll("g").data(xs).enter().append("g"),
gLower = svg.append("g").selectAll("g").data(xs).enter().append("g");
gUpper.append("rect")
.attr("x", function(d){ return d;})
.attr("y", 50)
.attr("width", size)
.attr("height",size)
.style({"fill": "#E6F9FF", "stroke-width": 2, "stroke": "black"});
gLower.append("rect")
.attr("x", function(d){ return d;})
.attr("y", 200)
.attr("width", size)
.attr("height",size)
.style({"fill": "#CFF0CA", "stroke-width": 2, "stroke": "black"});
gUpper.each(function (d,i) {
var g = d3.select(this);
clsbtn1.x(d + (size / 1.3)).y(70).clickEvent(function(){ g.remove(); });
g.call(clsbtn1);
})
gLower.each(function (d,i) {
var g = d3.select(this);
clsbtn2.x(d + (size / 1.4)).y(210).clickEvent(function(){ g.remove(); });
g.call(clsbtn2);
})
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment