InputBox object based on deeply tweaked SVG button by pbogden. Has minor warning "orm submission canceled because the form is not connected", so if anyone has any suggestion how to fix it — you're more than welcome.
Just leave your comments here.
InputBox object based on deeply tweaked SVG button by pbogden. Has minor warning "orm submission canceled because the form is not connected", so if anyone has any suggestion how to fix it — you're more than welcome.
Just leave your comments here.
d3.inputbox = function() { | |
var padding = 10, | |
radius = 3, | |
stdDeviation = 5, | |
offsetX = 2, | |
offsetY = 4; | |
function my(selection) { | |
selection.each(function(d, i) { | |
var g = d3.select(this) | |
.attr("id", "d3-inputbox" + i) | |
.attr("transform", "translate(" + d.x + "," + d.y + ")"); | |
var text = g.append("text").attr("dx", 12).attr("dy", d.height / 2 + 4).text(d.label.toUpperCase()); | |
var value = g.append("text").attr("id", "value").attr("dx", d.width - 12).attr("dy", d.height / 2 + 4).text("$" + d.value).classed("value", true); | |
var rect = g.insert("rect", "text", "value") | |
.attr("x", 0) | |
.attr("y", 0) | |
.attr("width", d.width) | |
.attr("height", d.height) | |
.attr("rx", radius) | |
.attr("ry", radius) | |
.on("mouseover", mouseover) | |
.on("mouseout", mouseout) | |
.on("click", click) | |
}); | |
} | |
function mouseover() { d3.select(this.parentNode).select("rect").classed("active", true) } | |
function mouseout() { d3.select(this.parentNode).select("rect").classed("active", false) } | |
function click(d, i) { | |
d3.selectAll("foreignObject").remove(); | |
var p = this.parentNode; | |
var field = d3.select(p); | |
var xy0 = this.getBBox(); | |
var xy1 = p.getBBox(); | |
xy0.x -= xy1.x - d.width + 96; | |
xy0.y -= xy1.y + 2 - 8; | |
var frm = field.append("foreignObject"); | |
var inp = frm | |
.attr("x", xy0.x) | |
.attr("y", xy0.y) | |
.attr("width", 80) | |
.attr("height", 32) | |
.append("xhtml:form") | |
.append("input") | |
.style("width", "80px") | |
.style("height", "16px") | |
.attr("type", "number") | |
.on("change", function() { | |
d.value = Number(this.value); | |
field.select("#value").text( "$" + d.value); | |
} ) | |
.attr("value", function() { return d.value; } ) | |
.on("keypress", function() { | |
var e = d3.event; | |
if (e.keyCode == 13){ | |
d.value = Number(inp.node().value); | |
field.select("foreignObject").remove(); | |
field.select("#value").text( "$" + d.value); | |
} | |
}); | |
} | |
return my; | |
} |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<title>D3.JS: InputBox</title> | |
<body> | |
<body> | |
<link rel="stylesheet" href="styles.css?v=1.0"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script src="d3.inputbox.js"></script> | |
<script> | |
var width = 960, height = 480; | |
var data = [{label: "Other Income", x: 32, y: 32, width: 280, height: 36.5, value: 0, function: function(){ fnA(); } }, | |
{label: "Student Loans", x: 32, y: 92, width: 280, height: 36.5, value: 0, function: function(){ fnB(); } }]; | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
var inputbox = d3.inputbox(); | |
var inputboxes = svg.selectAll(".inputbox") | |
.data(data) | |
.enter() | |
.append("g") | |
.attr("class", "inputbox") | |
.call(inputbox); | |
var fnA = function(){ console.log("functionA"); } | |
function fnB(){ console.log("functionB"); } | |
</script> |
@import url('https://fonts.googleapis.com/css?family=Open+Sans'); | |
body { | |
font-family: 'Open Sans', sans-serif; | |
} | |
.inputbox rect { | |
fill: #FFFFFF; | |
stroke: #348B6D; | |
stroke-width: 2px; | |
} | |
.inputbox rect.active { | |
fill: #D9F0E3; | |
} | |
.inputbox text { | |
font-family: 'Open Sans', sans-serif; | |
font-size: 12px; | |
letter-spacing: 3px; | |
fill: #494949; | |
pointer-events: none; | |
text-anchor: start; | |
-moz-user-select: none; | |
-webkit-user-select: none; | |
-ms-user-select: none; | |
} | |
.inputbox text.value { | |
text-anchor: end; | |
} |