Things are getting messed up because you've added mouseover
and mouseout
event listeners that try to perform actions that conflict with the ongoing transition events. To fix the problem, don't add the mouseover
/mouseout
listeners until after the chart bars have performed their initial transition. You can add a listener for the end of the transition using transition.on('end', function(){...}
and then add the mouse event listeners to the DOM elements once the transition has completed.
d3.select('#whateverItIs') // stuff to do prior to transition .transition() // transition stuff .on('end', function() { d3.select(this) .on("mouseover", function() { // handler code here }) .on("mouseout", function() { // handler code here }) })
With your code:
function draw() { var width = $(window).width(); var height = document.body.clientHeight; var data = [{ country: "Pichonita", growth: 15 }, { country: "Andromeda", growth: 12 }, { country: "India", growth: 33 }, { country: "Indonesia", growth: 22 }, { country: "Russia", growth: 6 }, { country: "Mars", growth: 41 }, { country: "Pluton", growth: 16 }, { country: "Earth", growth: 24 }, { country: "Neptune", growth: 8 } ]; //set margins var margin = { top: 30, right: 30, bottom: 30, left: 40 }; var width = width - margin.left - margin.right * 2.5; var height = height - margin.top - margin.bottom; //set scales & ranges var xScale = d3.scaleLinear() .range([0, width - 100]) var yScale = d3.scaleBand() .range([0, height]).padding(.2) //draw the svg var svg = d3.select("body") .append("svg") .attr("width", width + margin.left + margin.right * 3) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate("+ margin.left * 2 +","+ margin.top +")") //force data data.forEach(function(d) { return d.growth = +d.growth; }); //set domains yScale.domain(data.map(d => d.country)) xScale.domain([0, d3.max(data, d => d.growth)]) //add X & Y axes and append the bars to Y axis var xAxis = svg.append("g") .attr("class", xAxis) .attr("transform", "translate("+ 0 +","+ height +")") .call(d3.axisBottom(xScale)) var yAxis = svg.append("g") .attr("class", yAxis) .call(d3.axisLeft(yScale)) .selectAll("rect") .data(data) .enter() .append("rect") .attr("stroke", "transparent") .attr("stroke-width", 4) .attr("class", "bar") .attr("height", yScale.bandwidth()) .attr("x", 0.5) .attr("y", function(d) { return yScale(d.country) }) .attr("width", 0) .transition() .duration(3800) .delay((d, i) => (i + 1) * 200) .ease(d3.easeElastic) .attr("width", function(d) { return xScale(d.growth) }) .style("fill", "#00338D") .on('end', function() { d3.select(this) .on("mouseover", function() { d3.select(this) .transition().duration(600) .attr("stroke", "#6D2077") .attr("stroke-width", 3) .style("fill", "#6D2077") d3.selectAll(".textCircle") .transition().duration(600) .attr("r", yScale.bandwidth() / 1.9) .attr("stroke", "#6D2077") .attr("stroke-width", 1) }) .on("mouseout", function() { d3.select(this) .transition() .duration(600) .attr("stroke", "transparent") .attr("stroke-width", 0) .style("fill", "#00338D") d3.selectAll(".textCircle") .transition().duration(600) .attr("r", yScale.bandwidth() / 2) .attr("stroke", "transparent") }) }) var newG = svg.append("g") newG.selectAll("circle") .data(data) .enter() .append("circle") .attr("class", "textCircle") .attr("cx", d => xScale(d.growth)) .attr("cy", d => yScale(d.country) + yScale.bandwidth() / 2) .attr("r", 0) .transition() .duration(1200) .delay((d, i) => (i + 1) * 450) .attr("r", yScale.bandwidth() / 2) .attr("opacity", 1) .style("fill", "#0091DA") .attr("stroke", "transparent")}draw();$(window).resize(function() { $("body").empty(); draw();});
html{ height: 98%; margin: 0; padding: 0;}body{ min-height: 98%; margin: 0; padding: 0;}svg{ text-rendering: geometricPrecision; shape-rendering:geometricPrecision;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>