JSFiddle - React, Tailwind, and code Playground

by CoolBlue

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>

JavaScript

//interlocking between mouseover and mouseout due to no name on transitions
//more interlocking required to handle missed mouse outs
var width = 300;
var height = 300;

var svg = d3.select("body").append("svg")
		.attr({ width: width, height: height })
		.append("g")

var data = [50, 100, 150]

var inner_circles = svg.selectAll("innercircle").data(data)

inner_circles.enter().append("circle")
		.attr({ cy: height / 2, cx: function (d) { return d }, r: 5 })
		.attr("class", "innerCircle")
		.style("fill", "blue")

var outter_circles = svg.selectAll("outtercircle").data(data)

outter_circles.enter().append("circle")
		 .attr({ cy: height / 2, cx: function (d) { return d }, r: 10 })
		 .attr("class", "outterCircle")
		 .style("fill", "green")
				.style("border", "1px solid green")
		 .on("mouseover", mouseover)
		 .on("mouseout", mouseout);

function mouseover(d) {
	var outer = d3.select(this),
			inner = getInner(".innerCircle", outer),
			w = 3, r = 20;
	console.log("mouseover\t" + outer.datum())
	outer.transition()
		.call(_trans)
		.attr("r", r)
	inner.transition()
		.call(_trans)
		.attr("r", r - w)
		.delay(250)
	function _trans() {
		trans.call(this, 0.3, 0, "blue", w, "mouseover")
	}
}

function mouseout(d) {
	var outer = d3.select(this),
			inner = getInner(".innerCircle", outer)

	console.log("mouseout\t" + outer.datum())

	inner.transition()
		.call(_trans, "blue", 1)
		.attr("r", 5)
	outer.transition()
		.call(_trans, "green", 1)
		.attr("r", 10)
		.attr("fill-opacity", 1)
		.delay(250)
	function _trans(selection, s, w) {
		trans.call(this, 1, 1, s, w, "mouseout")
	}
}

function getInner(selector, ref) {
	return d3.selectAll(selector).filter(function (d) {
		return d === ref.datum()
	})
}
function trans(o, fo, s, w, name) {
	this
	.style("opacity", o)
	.style("fill-opacity", fo)
	.style("stroke", s)
	.style("stroke-width", w)
	.ease("sin")
	.duration(300)
	.each("interrupt", function() {console.log(name + "\tinterrupted*************")})
}